| 1 | #include<Memory.au3> |
|---|
| 2 | |
|---|
| 3 | Global Const $__Au3Obj_E_NOTIMPL = 0x80004001; |
|---|
| 4 | Global Const $__Au3Obj_S_OK = 0; |
|---|
| 5 | Global Const $__Au3Obj_E_NOINTERFACE = 0x80004002 |
|---|
| 6 | Global Const $__AU3Obj_DISP_E_UNKNOWNNAME = 0x80020006 |
|---|
| 7 | Global Const $__AU3Obj_DISP_E_EXCEPTION = 0x80020009 |
|---|
| 8 | |
|---|
| 9 | Global Const $__Au3Obj_vTable = DllStructCreate("ptr QueryInterface; ptr AddRef; ptr Release; ptr GetTypeInfoCount; ptr GetTypeInfo; ptr GetIDsOfNames; ptr Invoke;") |
|---|
| 10 | ; set DllCallbacks |
|---|
| 11 | Dim $aCallbacks[8] |
|---|
| 12 | $aCallbacks[1] = DllCallbackRegister("__Au3Obj_QueryInterface", "long", "ptr;dword;dword") ;QureyInterface |
|---|
| 13 | $aCallbacks[2] = DllCallbackRegister("__Au3Obj_AddRef", "long", "ptr") ;Addref |
|---|
| 14 | $aCallbacks[3] = DllCallbackRegister("__Au3Obj_Release", "long", "ptr") ;Release |
|---|
| 15 | $aCallbacks[4] = DllCallbackRegister("__Au3Obj_GetTypeInfoCount", "long", "ptr;ptr") |
|---|
| 16 | $aCallbacks[5] = DllCallbackRegister("__Au3Obj_GetTypeInfo", "long", "ptr;uint;int;ptr") |
|---|
| 17 | $aCallbacks[6] = DllCallbackRegister("__Au3Obj_GetIDsOfNames", "long", "ptr;ptr;ptr;uint;int;ptr") |
|---|
| 18 | $aCallbacks[7] = DllCallbackRegister("__Au3Obj_Invoke", "long", "ptr;int;ptr;int;ushort;ptr;ptr;ptr;ptr") |
|---|
| 19 | For $i = 1 To 7 |
|---|
| 20 | DllStructSetData($__Au3Obj_vTable, $i, DllCallbackGetPtr($aCallbacks[$i])) |
|---|
| 21 | Next |
|---|
| 22 | |
|---|
| 23 | ; In the end we still want the autoit object. This function converts a raw pointer to an autoit object |
|---|
| 24 | Func ConvertPtrToIDispatch($pIDispatch) |
|---|
| 25 | ; Author: monoceres |
|---|
| 26 | ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs... |
|---|
| 27 | ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us. |
|---|
| 28 | Local $aCall = DllCall("kernel32.dll", "none", "RtlMoveMemory", "idispatch*", 0, "ptr*", $pIDispatch, "dword", DllStructGetSize(DllStructCreate('ptr',1))) |
|---|
| 29 | If @error Then Return SetError(1, 0, 0) |
|---|
| 30 | Return $aCall[1] |
|---|
| 31 | EndFunc ;==>ConvertPtrToIDispatch |
|---|
| 32 | Func __Au3Obj_QueryInterface($pObject, $iid, $ppvObject) |
|---|
| 33 | ; Actually Autoit is not calling this function, so leave it empty for testing ;) |
|---|
| 34 | Return $__Au3Obj_E_NOINTERFACE |
|---|
| 35 | EndFunc ;==>__Au3Obj_QueryInterface |
|---|
| 36 | Func __Au3Obj_AddRef($pObject) |
|---|
| 37 | ; Author: Prog@ndy |
|---|
| 38 | Local $st = DllStructCreate("ptr;dword", $pObject) |
|---|
| 39 | Local $iCount = DllStructGetData($st, 2) + 1 |
|---|
| 40 | DllStructSetData($st, 2, $iCount) |
|---|
| 41 | Return $iCount |
|---|
| 42 | EndFunc ;==>__Au3Obj_AddRef |
|---|
| 43 | Func __Au3Obj_Release($pObject) |
|---|
| 44 | ; Author: Prog@ndy |
|---|
| 45 | Local $st = DllStructCreate("ptr;dword", $pObject) |
|---|
| 46 | Local $iCount = DllStructGetData($st, 2) - 1 |
|---|
| 47 | If $iCount < 0 Then Return 0 |
|---|
| 48 | DllStructSetData($st, 2, $iCount) |
|---|
| 49 | If $iCount = 0 Then ; delete Object |
|---|
| 50 | _MemGlobalFree($pObject) |
|---|
| 51 | EndIf |
|---|
| 52 | Return $iCount |
|---|
| 53 | EndFunc ;==>__Au3Obj_Release |
|---|
| 54 | Func __Au3Obj_GetTypeInfoCount($pObject, $pctinfo) |
|---|
| 55 | ; Author: Prog@ndy |
|---|
| 56 | Return $__Au3Obj_E_NOTIMPL |
|---|
| 57 | EndFunc ;==>__Au3Obj_GetTypeInfoCount |
|---|
| 58 | Func __Au3Obj_GetTypeInfo($pObject, $iTInfo, $lcid, $ppTInfo) |
|---|
| 59 | ; Author: Prog@ndy |
|---|
| 60 | Return $__Au3Obj_E_NOTIMPL |
|---|
| 61 | EndFunc ;==>__Au3Obj_GetTypeInfo |
|---|
| 62 | Func __Au3Obj_GetIDsOfNames($pObject, $riid, $rgszNames, $cNames, $lcid, $rgDispId) |
|---|
| 63 | Return $__AU3Obj_DISP_E_UNKNOWNNAME |
|---|
| 64 | EndFunc ;==>__Au3Obj_GetIDsOfNames |
|---|
| 65 | Func __Au3Obj_Invoke($pObject, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) |
|---|
| 66 | Return $__AU3Obj_DISP_E_EXCEPTION |
|---|
| 67 | EndFunc ;==>__Au3Obj_Invoke |
|---|
| 68 | |
|---|
| 69 | |
|---|
| 70 | ; construct object |
|---|
| 71 | Local $iSize = DllStructGetSize(DllStructCreate("ptr vTable; dword refcount;", 1)) |
|---|
| 72 | Local $pMem = _MemGlobalAlloc($iSize, $GPTR) ; will be freed in Objectz::release |
|---|
| 73 | Local $tStruct = DllStructCreate("ptr vTable; dword refcount;", $pMem) |
|---|
| 74 | DllStructSetData($tStruct, 1, DllStructGetPtr($__Au3Obj_vTable)) |
|---|
| 75 | $object = ConvertPtrToIDispatch($pMem) |
|---|
| 76 | OnAutoItExitRegister("__ReleaseObject") |
|---|
| 77 | |
|---|
| 78 | ;Test: Exit without releasing the object: |
|---|
| 79 | OnAutoItExitUnregister("__ReleaseObject") |
|---|
| 80 | |
|---|
| 81 | Func __ReleaseObject() |
|---|
| 82 | $object=0 |
|---|
| 83 | EndFunc |
|---|