Вроде как решился этот вопрос у меня следующим образом.
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function PutMem2 Lib "msvbvm60" (ByVal pWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function PutMem4 Lib "msvbvm60" (ByVal pDWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal pDWORDSrc As Long, ByVal pDWORDDst As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
и добавить функцию:
Public Function CallInterface(ByVal pInterface As Long, ByVal Member As Long, ByVal ParamsCount As Long, Optional ByVal p1 As Long = 0, Optional ByVal p2 As Long = 0, Optional ByVal p3 As Long = 0, Optional ByVal p4 As Long = 0, Optional ByVal p5 As Long = 0, Optional ByVal p6 As Long = 0, Optional ByVal p7 As Long = 0, Optional ByVal p8 As Long = 0, Optional ByVal p9 As Long = 0, Optional ByVal p10 As Long = 0) As Long
Dim i As Long, t As Long
Dim hGlobal As Long, hGlobalOffset As Long
If ParamsCount < 0 Then Err.Raise 5 'invalid call
If pInterface = 0 Then Err.Raise 5
'5 байт для запихивания каждого параметра в стек
'5 байт - PUSH this
'5 байт - вызов мембера
'3 байта - ret 0x0010, выпихивая при этом и параметры CallWindowProc
'1 байт - выравнивание, поскольку последний PutMem4 требует 4 байта.
hGlobal = GlobalAlloc(GMEM_FIXED, 5 * ParamsCount + 5 + 5 + 3 + 1)
If hGlobal = 0 Then Err.Raise 7 'insuff. memory
hGlobalOffset = hGlobal
If ParamsCount > 0 Then
t = VarPtr(p1)
For i = ParamsCount - 1 To 0 Step -1
PutMem2 hGlobalOffset, asmPUSH_imm32
hGlobalOffset = hGlobalOffset + 1
GetMem4 t + i * 4, hGlobalOffset
hGlobalOffset = hGlobalOffset + 4
Next
End If
'Первый параметр любого интерфейсного метода - this. Делаем...
PutMem2 hGlobalOffset, asmPUSH_imm32
hGlobalOffset = hGlobalOffset + 1
PutMem4 hGlobalOffset, pInterface
hGlobalOffset = hGlobalOffset + 4
'Вызов мембера интерфейса
PutMem2 hGlobalOffset, asmCALL_rel32
hGlobalOffset = hGlobalOffset + 1
GetMem4 pInterface, VarPtr(t) 'дереференс: находим положение vTable
GetMem4 t + Member * 4, VarPtr(t) 'смещение по vTable, после чего дереференс оного
PutMem4 hGlobalOffset, t - hGlobalOffset - 4
hGlobalOffset = hGlobalOffset + 4
'Интерфейсы stdcall. Поэтому не будем cdecl учитывать.
PutMem4 hGlobalOffset, &H10C2& 'ret 0x0010
CallInterface = CallWindowProc(hGlobal, 0, 0, 0, 0)
GlobalFree hGlobal
End Function
При инициализации ВК в процедуре IInitDone_Init вызываем эту функцию следующим образом:
Sub IInitDone_Init(ByVal Obj As Object)
Set V7Object = Obj
CallInterface ObjPtr(V7Object.AppDispatch), 1, 0
.....
End Sub
здесь 1 - это номер метода AddRef в интерфейсе IDispatch
После этого вызова 1С нормально закрывается после завершения работы, не оставляя за собой зависших процессов.
Статью по поводу этой функции и реализации дополнительных возможностей с ее помощью смотрите здесь:
http://www.realcoding.net/article/view/4097или здесь
http://www.vbnet.ru/articles/showarticle.aspx?id=204