Sign in to follow this  
Followers 0
wolf9228

Exe server (IDispatch Call)

5 posts in this topic

#1 ·  Posted (edited)

Exe server (IDispatch Call)

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683835(v=vs.85).aspx
;There are two main types of servers, in-process and out-of-process. In-process servers are implemented in a
;dynamic linked library (DLL), and out-of-process servers are implemented in an executable file (EXE). Out-of-process
;servers can reside either on the local computer or on a remote computer. In addition, COM provides a mechanism that
;allows an in-process server (a DLL) to run in a surrogate EXE process to gain the advantage of being able to run the
;process on a remote computer. For more information, see DLL Surrogates.

All project files
Exe_Server.zip

Program.au3

#include "Server32.au3"
#include <Array.au3>

StartRun()
Func ProgramMain()
$pDisp = DispatchCServerCreate()

$Return = DispCall($pDisp,"long","Server_DataTypeA",$DISPATCH_METHOD,"BYTE",1,"BYTE*",0,"BOOLEAN",2,"BOOLEAN*",0,"SHORT",3, _
"SHORT*",0,"USHORT",4,"USHORT*",0,"WORD",5,"WORD*",0,"INT",6,"INT*",0,"LONG",7,"LONG*",0,"BOOL",True,"BOOL*",0,"UINT",8, _
"UINT*",0,"ULONG",9,"ULONG*",0)

_ArrayDisplay($Return,"Server_DataTypeA")

$LPARAM_IN = _WinAPI_MakeLong(10,20)
$WPARAM_IN = _WinAPI_MakeLong(30,40)
$Return = DispCall($pDisp,"long","Server_DataTypeB",$DISPATCH_METHOD,"DWORD",1,"DWORD*",0,"INT64",2,"INT64*",0,"UINT64",3, _
"UINT64*",0,"FLOAT",3.4,"FLOAT*",0,"DOUBLE",5.5,"DOUBLE*",0,"LPARAM",$LPARAM_IN,"LPARAM*",0,"WPARAM",$WPARAM_IN,"WPARAM*",0, _
"VBOOL",8,"VBOOL*",0)

_ArrayDisplay($Return,"Server_DataTypeB")

$Return = DispCall($pDisp,"long","Server_BSTR",$DISPATCH_METHOD,"BSTR",StrToBstr("BSTR_NI"),"BSTR*",0)
$BSTR = $Return[2]
_ArrayDisplay($Return,"Server_BSTR")
MsgBox(0,"BSTR_OUT",BstrToStr($BSTR))

$Variant = DllStructCreate($tagVariant)
DllStructSetData($Variant,"vt",GetDataTypeNu("LONG"))
SetUnionOfVariant($Variant,"LONG",333)
$Return = DispCall($pDisp,"long","Server_VARIANT",$DISPATCH_METHOD,"VARIANT",DllStructGetPtr($Variant))
_ArrayDisplay($Return,"Server_VARIANT")
$BSTR = GetUnionOfVariant($Variant,"ptr")
MsgBox(0,"VARIANT_OUT",BstrToStr($BSTR))

$ARRAY = SafeArrayCreate("long",1000)
$Return = DispCall($pDisp,"long","Server_ARRAY",$DISPATCH_METHOD,"ARRAY",$ARRAY,"ARRAY*",0)
$ARRAY_OUT = $Return[2]
MsgBox(0,"ARRAY_OUT",$ARRAY_OUT)
_ArrayDisplay($Return,"Server_ARRAY")

$DoubleTime = GetDoubleTime(2014,1,7,10,3,20,10,0)
$Return = DispCall($pDisp,"long","Server_DATE",$DISPATCH_METHOD,"DATE",$DoubleTime,"DATE*",0)
$DATE_OUT = $Return[2]
$SystemTime = GetSystemTime($DATE_OUT)
_ArrayDisplay($SystemTime,"SystemTime")
_ArrayDisplay($Return,"Server_DATE")

$Return = DispCall($pDisp,"long","Server_CY",$DISPATCH_METHOD,"CY",GetCurrencyInt64(30,40),"CY*",0)
$CY_OUT = $Return[2]
$CurrencyStruct = GetCurrencyStruct($CY_OUT)
$MsgText = "Server_CY" & @CRLF & @CRLF
$MsgText &= "Lo = " & DllStructGetData($CurrencyStruct,1) & @CRLF
$MsgText &= "Hi = " & DllStructGetData($CurrencyStruct,2) & @CRLF
MsgBox(0,"CY_OUT",$MsgText)

$DECIMAL = DllStructCreate($tagDEC)
;-------------- Set In -----------
DllStructSetData($DECIMAL,2,2)
DllStructSetData($DECIMAL,3,3)
DllStructSetData($DECIMAL,4,4)
DllStructSetData($DECIMAL,5,5)
DllStructSetData($DECIMAL,6,6)
;-------------- Set In -----------
$Return = DispCall($pDisp,"long","Server_DECIMAL",$DISPATCH_METHOD,"DECIMAL",DllStructGetPtr($DECIMAL))

$MsgText = "Server_DECIMAL" & @CRLF & @CRLF
$MsgText &= "scale = " & DllStructGetData($DECIMAL,2) & @CRLF
$MsgText &= "sign = " & DllStructGetData($DECIMAL,3) & @CRLF
$MsgText &= "Hi32 = " & DllStructGetData($DECIMAL,4) & @CRLF
$MsgText &= "Lo32 = " & DllStructGetData($DECIMAL,5) & @CRLF
$MsgText &= "Mid32 = " & DllStructGetData($DECIMAL,6) & @CRLF
MsgBox(0,"DECIMAL_OUT",$MsgText)

Exit

While True
WEnd

EndFunc

Func StartRun()
CoInitializeEx(0,0)
if ($CmdLine[0]) Then
$Command = $CmdLine[1]
if ($Command == "ServerRun") Then
ServerMain()
Exit
EndIf
EndIf
ProgramMain()
Exit
EndFunc

Func ServerRun($TimeOut)
if (IsServerReady()) Then Return True
if (@Compiled) Then
Run(FileGetShortName(@AutoItExe) & " ServerRun")
Else
Run(FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath) & " ServerRun")
EndIf
$begin = TimerInit()
While ($TimeOut > TimerDiff($begin))
$IsServerReady = IsServerReady()
if ($IsServerReady) Then ExitLoop
WEnd
Return $IsServerReady
EndFunc

Func IsServerReady()
$IFactory = CoGetClassObject($CServeClsid,$CLSCTX_LOCAL_SERVER,0,$IID_IClassFactory) ; Get ClassFactory
if @error Then Return False
InterfaceCall($IFactory,"long",3) ; Release
Return True
EndFunc

Func DispatchCServerCreate()
ServerRun(5000)
$IFactory = CoGetClassObject($CServeClsid,$CLSCTX_LOCAL_SERVER,0,$IID_IClassFactory) ; Get ClassFactory
if @error Then Return SetError(1,0,0)
$Return = InterfaceCall($IFactory,"long",4,"ptr",0,"struct*",$IID_IDispatch,"ptr*",0) ; Call Factory_CreateInstance is Nu 4
if @error Or ($Return[0] <> 0) Then Return SetError(2,0,0)
$pDisp = $Return[3]
Return $pDisp
EndFunc

Server32.au3

#include "Class_Interface.au3"
#include "TypeInfo.au3"
#include <Array.au3>

Global $TypeInfo = 0
Global $CServeClsid = CLSIDFromString("{B331A1D3-F796-4A60-B429-7A911142EA54}")
Global $IID_IClassFactory = IIDFromString("{00000001-0000-0000-C000-000000000046}")
Global $IID_IDispatch = IIDFromString("{00020400-0000-0000-C000-000000000046}")

Func ServerMain()
$TypeInfo = MakeCServerTypeInfo()
if @error Then Exit
$FactoryPtr = NewIClassFactory()
if @error Then Exit
$dwRegister = CoRegisterClassObject($CServeClsid,$FactoryPtr,$CLSCTX_LOCAL_SERVER,$REGCLS_MULTIPLEUSE)
if @error Then Exit
While True
WEnd
EndFunc

Func NewIClassFactory()
Local $tagIClassFactory = "ULONG_PTR QueryInterface;ULONG_PTR AddRef;ULONG_PTR Release;" & _
"ULONG_PTR CreateInstance;ULONG_PTR LockServer;UINT AddRefCount"
$FactoryPtr = NewClass($tagIClassFactory)
if @error Then Return SetError(1,0,0)
SetClassMethod($FactoryPtr,"QueryInterface","Factory_QueryInterface","long","ptr;ptr;ptr")
if @error Then Return SetError(2,0,0)
SetClassMethod($FactoryPtr,"AddRef","Factory_AddRef","long","ptr")
if @error Then Return SetError(3,0,0)
SetClassMethod($FactoryPtr,"Release","Factory_Release","long","ptr")
if @error Then Return SetError(4,0,0)
SetClassMethod($FactoryPtr,"CreateInstance","Factory_CreateInstance","long","ptr;ptr;ptr;ptr")
if @error Then Return SetError(5,0,0)
SetClassMethod($FactoryPtr,"LockServer","Factory_LockServer","long","ptr;bool")
if @error Then Return SetError(6,0,0)
Factory_AddRef($FactoryPtr)
Return $FactoryPtr
EndFunc

Func NewCServe()
Local $tagServerClass = "ULONG_PTR QueryInterface;ULONG_PTR AddRef;ULONG_PTR Release;" & _
"ULONG_PTR GetTypeInfoCount;ULONG_PTR GetTypeInfo;ULONG_PTR GetIDsOfNames;ULONG_PTR Invoke;" & _
"ULONG_PTR DataTypeA;ULONG_PTR DataTypeB;ULONG_PTR BSTR;ULONG_PTR VARIANT;ULONG_PTR ARRAY;" & _
"ULONG_PTR DATE;ULONG_PTR CY;ULONG_PTR DECIMAL;UINT AddRefCount"
$ServerPtr = NewClass($tagServerClass)
if @error Then Return SetError(1,0,0)
SetClassMethod($ServerPtr,"QueryInterface","Server_QueryInterface","long","ptr;ptr;ptr")
if @error Then Return SetError(2,0,0)
SetClassMethod($ServerPtr,"AddRef","Server_AddRef","long","ptr")
if @error Then Return SetError(3,0,0)
SetClassMethod($ServerPtr,"Release","Server_Release","long","ptr")
if @error Then Return SetError(4,0,0)
SetClassMethod($ServerPtr,"GetTypeInfoCount","Server_GetTypeInfoCount","long","ptr;ptr")
if @error Then Return SetError(5,0,0)
SetClassMethod($ServerPtr,"GetTypeInfo","Server_GetTypeInfo","long","ptr;long;dword;ptr")
if @error Then Return SetError(6,0,0)
SetClassMethod($ServerPtr,"GetIDsOfNames","Server_GetIDsOfNames","long","ptr;ptr;ptr;long;dword;ptr")
if @error Then Return SetError(7,0,0)
SetClassMethod($ServerPtr,"Invoke","Server_Invoke","long","ptr;long;ptr;dword;word;ptr;ptr;ptr;ptr")
if @error Then Return SetError(8,0,0)
$MRegDataType = "PTR;BYTE;PTR;BOOLEAN;PTR;SHORT;PTR;USHORT;PTR;WORD;PTR;INT;PTR;LONG;PTR;BOOL;PTR;UINT;PTR;ULONG;PTR"
SetClassMethod($ServerPtr,"DataTypeA","Server_DataTypeA","long",$MRegDataType)
if @error Then Return SetError(9,0,0)
$MRegDataType = "PTR;DWORD;PTR;INT64;PTR;UINT64;PTR;FLOAT;PTR;DOUBLE;PTR;LPARAM;PTR;WPARAM;PTR;SHORT;PTR"
SetClassMethod($ServerPtr,"DataTypeB","Server_DataTypeB","long",$MRegDataType)
if @error Then Return SetError(10,0,0)
SetClassMethod($ServerPtr,"BSTR","Server_BSTR","long","PTR;PTR;PTR")
if @error Then Return SetError(11,0,0)
SetClassMethod($ServerPtr,"VARIANT","Server_VARIANT","long","PTR;PTR")
if @error Then Return SetError(12,0,0)
SetClassMethod($ServerPtr,"ARRAY","Server_ARRAY","long","PTR;PTR;PTR")
if @error Then Return SetError(13,0,0)
SetClassMethod($ServerPtr,"DATE","Server_DATE","long","PTR;double;PTR")
if @error Then Return SetError(14,0,0)
SetClassMethod($ServerPtr,"CY","Server_CY","long","PTR;INT64;PTR")
if @error Then Return SetError(15,0,0)
SetClassMethod($ServerPtr,"DECIMAL","Server_DECIMAL","long","PTR;PTR")
if @error Then Return SetError(16,0,0)
Server_AddRef($ServerPtr)
Return $ServerPtr
EndFunc

Func MakeCServerTypeInfo()

$InterfaceDataSt = MakeInterfaceData(15)
MakeMethodData($InterfaceDataSt,1,"Server_QueryInterface",2,"long")
MakeMethodData($InterfaceDataSt,2,"Server_AddRef",0,"long")
MakeMethodData($InterfaceDataSt,3,"Server_Release",0,"long")
MakeMethodData($InterfaceDataSt,4,"Server_GetTypeInfoCount",1,"long")
MakeMethodData($InterfaceDataSt,5,"Server_GetTypeInfo",3,"long")
MakeMethodData($InterfaceDataSt,6,"Server_GetIDsOfNames",5,"long")
MakeMethodData($InterfaceDataSt,7,"Server_Invoke",8,"long")
MakeMethodData($InterfaceDataSt,8,"Server_DataTypeA",20,"long")
MakeMethodData($InterfaceDataSt,9,"Server_DataTypeB",16,"long")
MakeMethodData($InterfaceDataSt,10,"Server_BSTR",2,"long")
MakeMethodData($InterfaceDataSt,11,"Server_VARIANT",1,"long")
MakeMethodData($InterfaceDataSt,12,"Server_ARRAY",2,"long")
MakeMethodData($InterfaceDataSt,13,"Server_DATE",2,"long")
MakeMethodData($InterfaceDataSt,14,"Server_CY",2,"long")
MakeMethodData($InterfaceDataSt,15,"Server_DECIMAL",1,"long")

MakeParamData($InterfaceDataSt,1,"ptr","riid","ptr","ppvObject")
MakeParamData($InterfaceDataSt,4,"ptr","pctinfo")
MakeParamData($InterfaceDataSt,5,"long","itinfo","DWORD","lcid","ptr","pptinfo")
MakeParamData($InterfaceDataSt,6,"ptr","riid","ptr","rgszNames","long","cNames","DWORD","lcid","ptr","rgdispid")
MakeParamData($InterfaceDataSt,7,"ptr","dispidMember","ptr","riid","DWORD","lcid","WORD","wFlags", _
"ptr","pdispParams","ptr","pvarResult","ptr","pExcepInfo","ptr","puArgErr")

MakeParamData($InterfaceDataSt,8,"BYTE","BYTE_IN","BYTE*","BYTE_OUT","BOOLEAN","BOOLEAN_IN","BOOLEAN*","BOOLEAN_OUT" _
,"SHORT","SHORT_IN","SHORT*","SHORT_OUT","USHORT","USHORT_IN","USHORT*","USHORT_OUT","WORD","WORD_IN","WORD*","WORD_OUT" _
,"INT","INT_IN","INT*","INT_OUT","LONG","LONG_IN","LONG*","LONG_OUT","BOOL","BOOL_IN","BOOL*","BOOL_OUT","UINT","UINT_IN", _
"UINT*","UINT_OUT","ULONG","ULONG_IN","ULONG*","ULONG_OUT")

MakeParamData($InterfaceDataSt,9,"DWORD","DWORD_IN","DWORD*","DWORD_OUT","INT64","INT64_IN","INT64*","INT64_OUT","UINT64", _
"UINT64_IN","UINT64*","UINT64_OUT","FLOAT","FLOAT_IN","FLOAT*","FLOAT_OUT","DOUBLE","DOUBLE_IN","DOUBLE*","DOUBLE_OUT", _
"LPARAM","LPARAM_IN","LPARAM*","LPARAM_OUT","WPARAM","WPARAM_IN","WPARAM*","WPARAM_OUT","VBOOL","VBOOL_IN","VBOOL*","VBOOL_OUT")

MakeParamData($InterfaceDataSt,10,"BSTR","BSTR_IN","BSTR*","BSTR_OUT")

MakeParamData($InterfaceDataSt,11,"VARIANT","VARIANT_IN_OUT")

MakeParamData($InterfaceDataSt,12,"ARRAY","ARRAY_IN","ARRAY*","ARRAY_OUT")

MakeParamData($InterfaceDataSt,13,"DATE","DATE_IN","DATE*","DATE_OUT")

MakeParamData($InterfaceDataSt,14,"CY","CY_IN","CY*","CY_OUT")

MakeParamData($InterfaceDataSt,15,"DECIMAL","DECIMAL_IN_OUT")

$TypeInfo = CreateDispTypeInfo($InterfaceDataSt)
if @error Then Return SetError(1,0,0)

Return $TypeInfo

EndFunc

Func Factory_QueryInterface($Interface,$riid,$ppvObject)
if ($ppvObject = 0) Then Return 0x80070057 ;E_INVALIDARG
SetOut("ULONG_PTR",$ppvObject,0)
if IsEqualIID($riid,"{00000000-0000-0000-C000-000000000046}") _ ; IUnknown
Or IsEqualIID($riid,"{00000001-0000-0000-C000-000000000046}") Then ; IClassFactory
SetOut("ULONG_PTR",$ppvObject,$Interface)
Else
Return 0x80004002 ; E_NOINTERFACE
EndIf
Factory_AddRef($Interface)
Return 0 ; NOERROR
EndFunc

Func Factory_AddRef($Interface)
$AddRefCount = (ClassGetData($Interface,"AddRefCount") + 1)
ClassSetData($Interface,"AddRefCount",$AddRefCount)
Return $AddRefCount
EndFunc

Func Factory_Release($Interface)
$AddRefCount = (ClassGetData($Interface,"AddRefCount") - 1)
ClassSetData($Interface,"AddRefCount",$AddRefCount)
if ($AddRefCount = 0) Then DeleteClass($Interface)
Return $AddRefCount
EndFunc

Func Factory_CreateInstance($Interface,$pUnkOuter,$riid,$ppvObject)
if ($ppvObject = 0) Then Return 0x80070057 ;E_INVALIDARG
SetOut("ULONG_PTR",$ppvObject,0)
if ($pUnkOuter) Then Return 0x80040110 ;CLASS_E_NOAGGREGATION
$ServerPtr = NewCServe()
if Not($ServerPtr) Then Return 0x80000002 ;E_OUTOFMEMORY
$hr = InterfaceCall($ServerPtr,"long",1,"ptr",$riid,"ptr",$ppvObject) ; QueryInterface
$hr = $hr[0]
Server_Release($ServerPtr)
Return $hr
EndFunc

Func Factory_LockServer($Interface,$fLock)
Return 0 ; NOERROR
EndFunc

Func Server_QueryInterface($Interface,$riid,$ppvObject)
if ($ppvObject = 0) Then Return 0x80070057 ;E_INVALIDARG
SetOut("ULONG_PTR",$ppvObject,0)
if IsEqualIID($riid,"{00000000-0000-0000-C000-000000000046}") _ ; IUnknown
Or IsEqualIID($riid,"{00020400-0000-0000-C000-000000000046}") Then ; IDispatch
SetOut("ULONG_PTR",$ppvObject,$Interface)
Else
Return 0x80004002 ; E_NOINTERFACE
EndIf
Server_AddRef($Interface)
Return 0 ; NOERROR
EndFunc

Func Server_AddRef($Interface)
$AddRefCount = (ClassGetData($Interface,"AddRefCount") + 1)
ClassSetData($Interface,"AddRefCount",$AddRefCount)
Return $AddRefCount
EndFunc

Func Server_Release($Interface)
$AddRefCount = (ClassGetData($Interface,"AddRefCount") - 1)
ClassSetData($Interface,"AddRefCount",$AddRefCount)
if ($AddRefCount = 0) Then DeleteClass($Interface)
Return $AddRefCount
EndFunc

Func Server_GetTypeInfoCount($Interface,$pctinfo)
if ($pctinfo = 0) Then Return 0x80000001 ;E_NOTIMPL
SetOut("UINT",$pctinfo,1)
Return 0 ; NOERROR
EndFunc

Func Server_GetTypeInfo($Interface,$itinfo,$lcid,$pptinfo)
if ($pptinfo = 0) Then Return 0x80070057 ;E_INVALIDARG
SetOut("ptr",$pptinfo,0)
if ($itinfo <> 0) Then Return 0x8002000B ; DISP_E_BADINDEX
InterfaceCall($TypeInfo,"long",2) ; AddRef
SetOut("ptr",$pptinfo,$TypeInfo)
Return 0 ; NOERROR
EndFunc

Func Server_GetIDsOfNames($Interface,$riid,$rgszNames,$cNames,$lcid,$rgdispid)
$hr = DllCall($OleAut32,"long","DispGetIDsOfNames","ptr",$TypeInfo,"ptr",$rgszNames,"long",$cNames,"ptr",$rgdispid)
$hr = $hr[0]
Return $hr
EndFunc

Func Server_Invoke($Interface,$dispidMember,$riid,$lcid,$wFlags,$pdispParams,$pvarResult,$pExcepInfo,$puArgErr)
$hr = DllCall($OleAut32,"long","DispInvoke","ptr",$Interface,"ptr",$TypeInfo,"int",$dispidMember,"WORD",$wFlags _
,"ptr",$pdispParams,"ptr",$pvarResult,"ptr",$pExcepInfo,"ptr",$puArgErr)
$hr = $hr[0]
Return $hr
EndFunc

Func Server_DataTypeA($Interface,$BYTE_IN,$BYTE_OUT,$BOOLEAN_IN,$BOOLEAN_OUT,$SHORT_IN,$SHORT_OUT,$USHORT_IN,$USHORT_OUT _
,$WORD_IN,$WORD_OUT,$INT_IN,$INT_OUT,$LONG_IN,$LONG_OUT,$BOOL_IN,$BOOL_OUT,$UINT_IN,$UINT_OUT,$ULONG_IN,$ULONG_OUT)


SetOut("BYTE",$BYTE_OUT,1)
SetOut("BOOLEAN",$BOOLEAN_OUT,True)
SetOut("SHORT",$SHORT_OUT,2)
SetOut("USHORT",$USHORT_OUT,4)
SetOut("WORD",$WORD_OUT,5)
SetOut("INT",$INT_OUT,6)
SetOut("LONG",$LONG_OUT,7)
SetOut("BOOL",$BOOL_OUT,False)
SetOut("UINT",$UINT_OUT,8)
SetOut("ULONG",$ULONG_OUT,9)

$MsgText = "Server_DataTypeA" & @CRLF & @CRLF
$MsgText &= "BYTE_IN ==> "
$MsgText &= $BYTE_IN & @CRLF
$MsgText &= "BOOLEAN_IN ==> "
$MsgText &= $BOOLEAN_IN & @CRLF
$MsgText &= "SHORT_IN ==> "
$MsgText &= $SHORT_IN & @CRLF
$MsgText &= "USHORT_IN ==> "
$MsgText &= $USHORT_IN & @CRLF
$MsgText &= "WORD_IN ==> "
$MsgText &= $WORD_IN & @CRLF
$MsgText &= "INT_IN ==> "
$MsgText &= $INT_IN & @CRLF
$MsgText &= "LONG_IN ==> "
$MsgText &= $LONG_IN & @CRLF
$MsgText &= "BOOL_IN ==> "
$MsgText &= $BOOL_IN & @CRLF
$MsgText &= "UINT_IN ==> "
$MsgText &= $UINT_IN & @CRLF
$MsgText &= "ULONG_IN ==> "
$MsgText &= $ULONG_IN & @CRLF

MsgBox(0,"Server_DataTypeA",$MsgText)

Return 100

EndFunc


Func Server_DataTypeB($Interface,$DWORD_IN,$DWORD_OUT,$INT64_IN,$INT64_OUT,$UINT64_IN,$UINT64_OUT,$FLOAT_IN,$FLOAT_OUT,$DOUBLE_IN _
,$DOUBLE_OUT,$LPARAM_IN,$LPARAM_OUT,$WPARAM_IN,$WPARAM_OUT,$VBOOL_IN,$VBOOL_OUT)

SetOut("DWORD",$DWORD_OUT,10)
SetOut("INT64",$INT64_OUT,11)
SetOut("UINT64",$UINT64_OUT,12)
SetOut("FLOAT",$FLOAT_OUT,13.5)
SetOut("DOUBLE",$DOUBLE_OUT,14.6)
SetOut("LPARAM",$LPARAM_OUT,_WinAPI_MakeLong(50, 60))
SetOut("WPARAM",$WPARAM_OUT,_WinAPI_MakeLong(70, 80))
SetOut("SHORT",$VBOOL_OUT,17)

$MsgText = "Server_DataTypeB" & @CRLF & @CRLF
$MsgText &= "DWORD_IN ==> "
$MsgText &= $DWORD_IN & @CRLF
$MsgText &= "INT64_IN ==> "
$MsgText &= $INT64_IN & @CRLF
$MsgText &= "UINT64_IN ==> "
$MsgText &= $UINT64_IN & @CRLF
$MsgText &= "FLOAT_IN ==> "
$MsgText &= $FLOAT_IN & @CRLF
$MsgText &= "DOUBLE_IN ==> "
$MsgText &= $DOUBLE_IN & @CRLF
$MsgText &= "LPARAM_IN ==> "
$MsgText &= $LPARAM_IN & @CRLF
$MsgText &= "LPARAM_HiWord ==> "
$MsgText &= _WinAPI_HiWord($LPARAM_IN) & @CRLF
$MsgText &= "LPARAM_LoWord ==> "
$MsgText &= _WinAPI_LoWord($LPARAM_IN) & @CRLF
$MsgText &= "WPARAM_IN ==> "
$MsgText &= $WPARAM_IN & @CRLF
$MsgText &= "WPARAM_HiWord ==> "
$MsgText &= _WinAPI_HiWord($WPARAM_IN) & @CRLF
$MsgText &= "WPARAM_LoWord ==> "
$MsgText &= _WinAPI_LoWord($WPARAM_IN) & @CRLF
$MsgText &= "SHORT_IN Or VBOOL_IN ==> "
$MsgText &= $VBOOL_IN & @CRLF
MsgBox(0,"Server_DataTypeB",$MsgText)

Return 200

EndFunc

Func Server_BSTR($Interface,$BSTR_IN,$BSTR_OUT)
SetOut("PTR",$BSTR_OUT,StrToBstr("BSTR_OUT"))
MsgBox(0,"BSTR_IN",BstrToStr($BSTR_IN))
Return 400
EndFunc

Func Server_VARIANT($Interface,$VARIANT_IN_OUT)
$Variant = DllStructCreate($tagVariant,$VARIANT_IN_OUT)
$Long = GetUnionOfVariant($Variant,"long")
MsgBox(0,"VARIANT_IN",$Long)
DllStructSetData($Variant,"vt",GetDataTypeNu("BSTR"))
SetUnionOfVariant($Variant,"ptr",StrToBstr("VARIANT_OUT"))
Return 500
EndFunc


Func Server_ARRAY($Interface,$ARRAY_IN,$ARRAY_OUT)
SetOut("PTR",$ARRAY_OUT,SafeArrayCreate("byte",1,1000))
MsgBox(0,"ARRAY_IN",$ARRAY_IN)
Return 700
EndFunc

Func Server_DATE($Interface,$DATE_IN,$DATE_OUT)
$DoubleTime = GetDoubleTime(2014,1,7,10,3,20,10,0)
SetOut("double",$DATE_OUT,$DoubleTime)
$TimeArray = GetSystemTime($DATE_IN)
$MsgText = "Server_DATE" & @CRLF & @CRLF
$MsgText &= $TimeArray[0][1] & " = " & $TimeArray[0][0] & @CRLF
$MsgText &= $TimeArray[1][1] & " = " & $TimeArray[1][0] & @CRLF
$MsgText &= $TimeArray[2][1] & " = " & $TimeArray[2][0] & @CRLF
$MsgText &= $TimeArray[3][1] & " = " & $TimeArray[3][0] & @CRLF
$MsgText &= $TimeArray[4][1] & " = " & $TimeArray[4][0] & @CRLF
$MsgText &= $TimeArray[5][1] & " = " & $TimeArray[5][0] & @CRLF
$MsgText &= $TimeArray[6][1] & " = " & $TimeArray[6][0] & @CRLF
$MsgText &= $TimeArray[7][1] & " = " & $TimeArray[7][0]
MsgBox(0,"DATE_IN",$MsgText)
Return 800
EndFunc

Func Server_CY($Interface,$CY_IN,$CY_OUT)
SetOut("Int64",$CY_OUT,GetCurrencyInt64(10,20))
$CurrencyStruct = GetCurrencyStruct($CY_IN)
$MsgText = "Server_CY" & @CRLF & @CRLF
$MsgText &= "Lo = " & DllStructGetData($CurrencyStruct,1) & @CRLF
$MsgText &= "Hi = " & DllStructGetData($CurrencyStruct,2) & @CRLF
MsgBox(0,"CY_IN",$MsgText)
Return 900
EndFunc

Func Server_DECIMAL($Interface,$DECIMAL_IN_OUT)

$DECIMAL = DllStructCreate($tagDEC,$DECIMAL_IN_OUT)
$MsgText = "Server_DECIMAL" & @CRLF & @CRLF
$MsgText &= "scale = " & DllStructGetData($DECIMAL,2) & @CRLF
$MsgText &= "sign = " & DllStructGetData($DECIMAL,3) & @CRLF
$MsgText &= "Hi32 = " & DllStructGetData($DECIMAL,4) & @CRLF
$MsgText &= "Lo32 = " & DllStructGetData($DECIMAL,5) & @CRLF
$MsgText &= "Mid32 = " & DllStructGetData($DECIMAL,6) & @CRLF
MsgBox(0,"DECIMAL_IN",$MsgText)

;-------------- Set Out -----------
DllStructSetData($DECIMAL,2,7)
DllStructSetData($DECIMAL,3,8)
DllStructSetData($DECIMAL,4,9)
DllStructSetData($DECIMAL,5,10)
DllStructSetData($DECIMAL,6,11)
;-------------- Set Out -----------

Return 1000
EndFunc

Class_Interface.au3

#include "Constants.au3"
#include "DataType.au3"

Func NewClass($tagClass)
$ClassStA = DllStructCreate($tagClass)
if @error Then Return SetError(1,0,0)
$ClassStB = DllStructCreate("ULONG_PTR")
if @error Then Return SetError(2,0,0)
DllStructSetData($ClassStB,1,DllStructGetPtr($ClassStA))
$ClassStBPtr = DllStructGetPtr($ClassStB)
$UBound = (UBound($StOfClassArray) - 1)
$StOfClassArray[$UBound][0] = $ClassStA
$StOfClassArray[$UBound][1] = $ClassStB
$StOfClassArray[$UBound][2] = $ClassStBPtr
ReDim $StOfClassArray[$UBound + 2][4]
Return $ClassStBPtr
EndFunc

Func SetClassMethod($ClassStBPtr,$MethodName,$FuncName,$ReturnDataType,$ParamsDataType)
$Element = FindClassSt($ClassStBPtr)
if @error Then Return SetError(1,0,False)
$ClassStA = $StOfClassArray[$Element][0]
DllStructGetData($ClassStA,$MethodName)
if @error Then Return SetError(2,0,False)
$RegCallbackFunc = DllCallbackRegister($FuncName,$ReturnDataType,$ParamsDataType)
if Not($RegCallbackFunc) Then Return SetError(3,0,False)
$CallbackFuncPtr = DllCallbackGetPtr($RegCallbackFunc)
$RegFuncArray = $StOfClassArray[$Element][3]
if Not IsArray($RegFuncArray) Then
Dim $RegFuncArray[1]
Else
ReDim $RegFuncArray[(UBound($RegFuncArray) + 1)]
EndIf
$RegFuncArray[(UBound($RegFuncArray) - 1)] = $RegCallbackFunc
$StOfClassArray[$Element][3] = $RegFuncArray
DllStructSetData($ClassStA,$MethodName,$CallbackFuncPtr)
Return True
EndFunc

Func ClassSetData($ClassStBPtr,$ElementName,$Value)
$Element = FindClassSt($ClassStBPtr)
if @error Then Return SetError(1,0,False)
$ClassStA = $StOfClassArray[$Element][0]
DllStructSetData($ClassStA,$ElementName,$Value)
if @error Then Return SetError(2,0,False)
Return True
EndFunc

Func ClassGetData($ClassStBPtr,$ElementName)
$Element = FindClassSt($ClassStBPtr)
if @error Then Return SetError(1,0,0)
$ClassStA = $StOfClassArray[$Element][0]
$Value = DllStructGetData($ClassStA,$ElementName)
if @error Then Return SetError(2,0,0)
Return $Value
EndFunc

Func ClassGetElementPtr($ClassStBPtr,$ElementName)
$Element = FindClassSt($ClassStBPtr)
if @error Then Return SetError(1,0,0)
$ClassStA = $StOfClassArray[$Element][0]
$ElementPtr = DllStructGetPtr($ClassStA,$ElementName)
if @error Then Return SetError(2,0,0)
Return $ElementPtr
EndFunc

Func FindClassSt($ClassStBPtr)
For $Element = 0 To (UBound($StOfClassArray) - 2)
if ($ClassStBPtr = $StOfClassArray[$Element][2]) Then Return $Element
Next
Return SetError(1,0,-1)
EndFunc

Func DeleteClass($ClassStBPtr)
Local $UBound = UBound($StOfClassArray)
Dim $NewStOfClassArray[$UBound][4]
Local $iElement = 0 , $TestDelete = False
For $Element = 0 To ($UBound - 2)
if ($ClassStBPtr = $StOfClassArray[$Element][2]) Then
$RegFuncArray = $StOfClassArray[$Element][3]
For $nElement = 0 To UBound($RegFuncArray) - 1
$RegCallbackFunc = $RegFuncArray[$nElement]
DllCallbackFree($RegCallbackFunc)
Next
$TestDelete = True
Else
$NewStOfClassArray[$iElement][0] = $StOfClassArray[$Element][0]
$NewStOfClassArray[$iElement][1] = $StOfClassArray[$Element][1]
$NewStOfClassArray[$iElement][2] = $StOfClassArray[$Element][2]
$NewStOfClassArray[$iElement][3] = $StOfClassArray[$Element][3]
$iElement += 1
EndIf
Next
if ($TestDelete) Then
if ($UBound > 1) Then ReDim $NewStOfClassArray[$UBound - 1][4]
$StOfClassArray = $NewStOfClassArray
Return True
Else
Return SetError(1,0,False)
EndIf
EndFunc

Func SetOut($DataType,$OutPtr,$SetValue)
Return DllStructSetData(DllStructCreate($DataType,$OutPtr),1,$SetValue)
EndFunc

Func GetOut($DataType,$OutPtr)
Return DllStructGetData(DllStructCreate($DataType,$OutPtr),1)
EndFunc


Func IsEqualIID($IID_A,$IID_B)

if Not IsString($IID_A) Then
$IID_A = _WinAPI_StringFromGUID($IID_A)
if $IID_A == "" Then Return SetError(1,0,False)
Else
if Not IsDllStruct(_WinAPI_GUIDFromString($IID_A)) Then Return SetError(1,0,False)
EndIf

if Not IsString($IID_B) Then
$IID_B = _WinAPI_StringFromGUID($IID_B)
if $IID_B == "" Then Return SetError(2,0,False)
Else
if Not IsDllStruct(_WinAPI_GUIDFromString($IID_B)) Then Return SetError(2,0,False)
EndIf

if ($IID_A == $IID_B) Then
Return True
Else
Return False
EndIf

EndFunc

Func DispCall($pDisp,$RtType,$MemberName,$MemberType,$Type1 = "",$Param1 = 0,$Type2 = "",$Param2 = 0 _
,$Type3 = "",$Param3 = 0, $Type4 = "", $Param4 = 0,$Type5 = 0 ,$Param5 = 0, $Type6 = "", $Param6 = 0 _
,$Type7 = "",$Param7 = 0,$Type8 = "", $Param8 = 0,$Type9 = "",$Param9 = 0,$Type10 = "", $Param10 = 0 _
,$Type11= "",$Param11= 0,$Type12= "", $Param12= 0,$Type13= "",$Param13 = 0,$Type14 = "",$Param14 = 0 _
,$Type15= "",$Param15= 0,$Type16= "", $Param16= 0,$Type17= "",$Param17 = 0,$Type18 = "",$Param18 = 0 _
,$Type19= "",$Param19= 0,$Type20= "", $Param20= 0,$Type21= "",$Param21 = 0,$Type22 = "",$Param22 = 0 _
,$Type23= "",$Param23= 0,$Type24= "", $Param24= 0,$Type25= "",$Param25 = 0,$Type26 = "",$Param26 = 0 _
,$Type27= "",$Param27= 0,$Type28= "", $Param28= 0,$Type29= "",$Param29 = 0,$Type30 = "",$Param30 = 0)

if ((@NumParams > 4) And (Mod((@NumParams - 4),2) <> 0)) Then Return SetError(1,0,0)
Local $NumParams = ((@NumParams - 4) / 2)

$ptNameSt = DllStructCreate("WCHAR[" & (StringLen($MemberName) + 1) & "]")
DllStructSetData($ptNameSt,1,$MemberName)
$StArrayName = DllStructCreate("ptr")
DllStructSetData($StArrayName,1,DllStructGetPtr($ptNameSt))

$HRESULT = InterfaceCall($pDisp,"long",6,"struct*",$IID_NULL,"struct*",$StArrayName,"UINT",1,"DWORD",0,"long*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(2,0,0)
; Call Server_GetIDsOfNames Is Nu 6
Local $dispID = $HRESULT[5]

$rgvarg = DllStructCreate("byte[" & ($VariantSize * $NumParams) & "]")
$rgvargPtr = DllStructGetPtr($rgvarg)

Local $nReturn[$NumParams + 1][2] , $Variant = 0 , $RtVariant = 0 , $DISPID_PROPERTYPUT = -3
For $i = 0 To $NumParams

if ($i = 0) Then

$RtVariant = DllStructCreate($tagVariant)
$Variant = $RtVariant

$Value = ""
$DataType = $RtType

$DataTypeNu = GetDataTypeNu($DataType)
if @error Then Return SetError(3,0,0)

Else

$Variant = DllStructCreate($tagVariant,$rgvargPtr + (($NumParams - $i) * $VariantSize))

$Value = Eval("Param" & $i)
$DataType = Eval("Type" & $i)

$DataTypeNu = GetDataTypeNu($DataType)
if @error Then Return SetError(3,0,0)

EndIf

$BOOLREF = @extended
$DataType = StringReplace($DataType,"*","")
$nReturn[$i][0] = $BOOLREF

Switch $DataType
Case "BSTR","DISPATCH","UNKNOWN","ARRAY"
Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef()
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"ptr",$Value)
EndSwitch

Case "VARIANT","DECIMAL"
if Not IsPtr($Value) Or $Value = Ptr(0) Then Return SetError(4,0,0)
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"ptr",$Value)

Case "CY"
Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef("INT64")
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"INT64",$Value)
EndSwitch

Case "DATE"
Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef("double")
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"double",$Value)
EndSwitch

Case "ERROR" ;Scode
Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef("long")
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"long",$Value)
EndSwitch

Case "VBOOL" ;VARIANT_BOOL short A 16-bit ;typedef short VARIANT_BOOL;
Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef("short")
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,"short",$Value)
EndSwitch

Case Else

Switch $BOOLREF
Case True
$nReturn[$i][1] = MakByRef($DataType)
SetUnionOfVariant($Variant,"ptr",DllStructGetPtr($nReturn[$i][1]))
Case False
$nReturn[$i][1] = $Value
SetUnionOfVariant($Variant,$DataType,$Value)
EndSwitch

EndSwitch

DllStructSetData($Variant,"vt",$DataTypeNu)
Next

$DISPPARAMS = DllStructCreate($tagDISPPARAMS)
DllStructSetData($DISPPARAMS,"cArgs",$NumParams)
DllStructSetData($DISPPARAMS,"rgvarg",$rgvargPtr)
if BitAND($MemberType,$DISPATCH_PROPERTYPUT) Then
$rgdispidNamedArgsSt = DllStructCreate("long")
DllStructSetData($rgdispidNamedArgsSt,1,$DISPID_PROPERTYPUT)
DllStructSetData($DISPPARAMS,"rgdispidNamedArgs",DllStructGetPtr($rgdispidNamedArgsSt))
DllStructSetData($DISPPARAMS,"cNamedArgs",1)
EndIf

$HRESULT = InterfaceCall($pDisp,"long",7,"long",$dispID,"struct*",$IID_NULL,"DWORD",0, _
"WORD",$MemberType,"struct*",$DISPPARAMS,"struct*",$RtVariant,"ptr*",0,"UINT*",0)
; Call Server_Invoke Is Nu 7
if @error Or $HRESULT[0] <> 0 Then Return SetError(5,0,0)

Local $vReturn[($NumParams + 1)]
For $i = 0 To $NumParams
$BOOLREF = $nReturn[$i][0]
$Value = $nReturn[$i][1]
if ($i = 0) Then
if ($BOOLREF) Then
if IsDllStruct($Value) Then $Value = GetByRefValue($Value)
$vReturn[$i] = $Value
Else
$vReturn[$i] = GetUnionOfVariant($RtVariant,$RtType)
EndIf
Else
if ($BOOLREF) Then
if IsDllStruct($Value) Then $Value = GetByRefValue($Value)
$vReturn[$i] = $Value
Else
$vReturn[$i] = $Value
EndIf
EndIf
Next

Return $vReturn

EndFunc


Func InterfaceCall($Inface,$ReturnType,$MethodNum,$Type1 = 0,$Param1 = 0,$Type2 = 0,$Param2 = 0 _
,$Type3 = 0,$Param3 = 0, $Type4 = 0,$Param4 = 0 ,$Type5 = 0 ,$Param5 = 0,$Type6 = 0,$Param6 = 0 _
,$Type7 = 0,$Param7 = 0, $Type8 = 0,$Param8 = 0,$Type9 = 0,$Param9 = 0,$Type10 = 0,$Param10 = 0 _
,$Type11= 0,$Param11= 0,$Type12= 0,$Param12= 0,$Type13= 0,$Param13 = 0,$Type14 = 0,$Param14 = 0 _
,$Type15= 0,$Param15= 0,$Type16= 0,$Param16= 0,$Type17= 0,$Param17 = 0,$Type18 = 0,$Param18 = 0 _
,$Type19= 0,$Param19= 0,$Type20= 0,$Param20= 0,$Type21= 0,$Param21 = 0,$Type22 = 0,$Param22 = 0 _
,$Type23= 0,$Param23= 0,$Type24= 0,$Param24= 0,$Type25= 0,$Param25 = 0,$Type26 = 0,$Param26 = 0 _
,$Type27= 0,$Param27= 0,$Type28= 0,$Param28= 0,$Type29= 0,$Param29 = 0,$Type30 = 0,$Param30 = 0)
;;Return Array Of DllCallAddress
;Only Call Virtual Method Form any Class Or From any Interface
;$MethodNum ==> Virtual Method Number In (Virtual Methods Table) ;See the examples
;-------------------------------------------------------------------;C++ Example1
;C++ Example1
;class iClass
;{
;public:
;void MethodA()
;{
;MessageBox(0,"MethodA","MSG",0);
;}
;virtual void VirtualMethodB()
;{
;MessageBox(0,"VirtualMethodB","MSG",0);
;}
;virtual void VirtualMethodC()
;{
;MessageBox(0,"VirtualMethodC","MSG",0);
;}
;void MethodB()
;{
;MessageBox(0,"MethodB","MSG",0);
;}
;virtual void VirtualMethodA()
;{
;MessageBox(0,"VirtualMethodA","MSG",0);
;}
;};
;-----------------------------------------------------------;Virtual Methods Table
;Virtual Methods Table
;virtual void VirtualMethodB() ==> Virtual Method Number Is 1
;virtual void VirtualMethodC() ==> Virtual Method Number Is 2
;virtual void VirtualMethodA() ==> Virtual Method Number Is 3
;-----------------------------------------------------------;Virtual Methods Table
;-------------------------------------------------------------------;C++ Example1

;////////////////////////////////////////////////////////////////////////////////

;-------------------------------------------------------------------;C++ Example2
;C++ Example2
;class iClassA
;{
;public:
;void MethodA()
;{
;MessageBox(0,"MethodA","MSG",0);
;}
;virtual void VirtualMethodB()
;{
;MessageBox(0,"VirtualMethodB","MSG",0);
;}
;virtual void VirtualMethodC()
;{
;MessageBox(0,"VirtualMethodC","MSG",0);
;}
;};

;class iClassB : public iClassA
;{
;public:
;void MethodD()
;{
;MessageBox(0,"MethodD","MSG",0);
;}
;virtual void VirtualMethodF()
;{
;MessageBox(0,"VirtualMethodF","MSG",0);
;}
;virtual void VirtualMethodE()
;{
;MessageBox(0,"VirtualMethodE","MSG",0);
;}
;};
;////////////////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////
;------------------------------------------;Virtual Methods Table Of iClassA Class
;Virtual Methods Table Of iClassA Class
;virtual void VirtualMethodB() ==> Virtual Method Number Is 1
;virtual void VirtualMethodC() ==> Virtual Method Number Is 2
;------------------------------------------;Virtual Methods Table Of iClassA Class
;////////////////////////////////////////////////////////////////////////////////
;///////////////////////////////////////////////////////////////////////////////
;------------------------------------------;Virtual Methods Table Of iClassB Class
;class iClassB : public iClassA
;base class ==> iClassA
;derived class ==> iClassB
;http://msdn.microsoft.com/en-us/library/hzk8a7d3.aspx
;When preceding the name of a base class, the public keyword specifies that the public
;and protected members of the base class are public and protected members, respectively,
;of the derived class.
;-------------------------------------------------------------------------------------
;Virtual Methods Table Of iClassB Class
;virtual void VirtualMethodB() In (iClassA) ==> Virtual Method Number Is 1
;virtual void VirtualMethodC() In (iClassA) ==> Virtual Method Number Is 2
;virtual void VirtualMethodF() In (iClassB) ==> Virtual Method Number Is 3
;virtual void VirtualMethodE() In (iClassB) ==> Virtual Method Number Is 4
;------------------------------------------;Virtual Methods Table Of iClassB Class
;-------------------------------------------------------------------;C++ Example2
;////////////////////////////////////////////////////////////////////////////////
if Not IsPtr($Inface) Or ($MethodNum < 1) Then Return SetError(1,0,0)
if (@NumParams > 3) And (Mod((@NumParams - 3),2) <> 0) Then Return SetError(2,0,0)
Local $iMethAddress = GetMethodAddress($Inface,$MethodNum)
if Not ($iMethAddress) Then Return SetError(3,0,0)
Local $iDataType = "",$iFuncParam = "",$iCommand = "",$iReturn = 0
;Why use Inface Param In DllCallAddress Function Because the Function of the method
;starts from the (Interface Or class)
;See here
;int class::MethodFunction( int Param ){return 0;};
$iCommand = 'DllCallAddress("' & $ReturnType & '",Eval("iMethAddress"),"ptr",Eval("Inface"),'
For $i = 1 To ((@NumParams - 3) / 2)
$iDataType = Eval("Type" & $i)
$iCommand &= '"' & $iDataType & '",'
$iFuncParam = 'Eval("Param' & $i & '"),'
$iCommand &= $iFuncParam
Next
$iCommand = StringTrimRight($iCommand,1)
$iCommand &= ")"
$iReturn = Execute($iCommand)
if @error Then Return SetError(4,0,0)
Local $nReturn[UBound($iReturn) -1] , $j = 0
For $i = 0 To UBound($iReturn) - 1
if ($i = 1) Then ContinueLoop ;Skip $Inface Element
$nReturn[$j] = $iReturn[$i]
$j += 1
Next
Return SetError(0,0,$nReturn)
EndFunc

Func GetMethodAddress($Inface,$MethodNum)
;$MethodNum ==> Virtual Method Number In (Virtual Methods Table)
Local $iMethAddress = 0,$OutCastStruct1 = 0
Local $OutCast1 = 0 , $OutCastStruct2 = 0
if Not IsPtr($Inface) Or ($MethodNum < 1) Then Return SetError(1,0,0)
;-------------------------------------------------------
$OutCastStruct1 = DllStructCreate("ULONG_PTR",$Inface)
$OutCast1 = DllStructGetData($OutCastStruct1,1)
;In C++ ==> unsigned long** OutCast1 = *(unsigned long***)Inface;
;--------------------------------------------------------
;-------------------------------------------------------
$OutCastStruct2 = DllStructCreate("ULONG_PTR",$OutCast1 + ($SizeOfUlong_Ptr * ($MethodNum - 1)))
$iMethAddress = DllStructGetData($OutCastStruct2,1)
;$OutCast1 + ($SizeOfUlong_Ptr * ($MethodNum - 1)) ==> $OutCast1 Is PTR Array Of Virtual Methods Table // Method PTR = Array[MethodNum - 1]
;In C++ ==> unsigned long* iMethAddress = *(unsigned long**)((BYTE*)OutCast1 + (SizeOfUlong_Ptr * (MethodNum - 1)));
;Or In C++ ==> unsigned long* iMethAddress = OutCast1[MethodNum - 1];
;--------------------------------------------------------
if (IsBadCodePtr($iMethAddress)) Then Return SetError(2,0,0)
Return SetError(0,0,$iMethAddress)
EndFunc

Func GetCount_Of_VirtualMethods($Inface)
Local $iMethAddress = 0,$OutCastStruct1 = 0
Local $OutCast1 = 0 , $OutCastStruct2 = 0 , $MethodNum = 1
if Not IsPtr($Inface) Then Return SetError(1,0,0)
;-------------------------------------------------------
$OutCastStruct1 = DllStructCreate("ULONG_PTR",$Inface)
$OutCast1 = DllStructGetData($OutCastStruct1,1)
;In C++ ==> unsigned long** OutCast1 = *(unsigned long***)Inface;
;--------------------------------------------------------
While 1
;-------------------------------------------------------
$OutCastStruct2 = DllStructCreate("ULONG_PTR",DllStructGetData($OutCastStruct1,1) + ($SizeOfUlong_Ptr * ($MethodNum - 1)))
$iMethAddress = DllStructGetData($OutCastStruct2,1)
;$OutCast1 + ($SizeOfUlong_Ptr * ($MethodNum - 1)) ==> $OutCast1 Is PTR Array Of Virtual Methods Table // Method PTR = Array[MethodNum - 1]
;In C++ ==> unsigned long* iMethAddress = *(unsigned long**)((BYTE*)OutCast1 + (SizeOfUlong_Ptr * (MethodNum - 1)));
;Or In C++ ==> unsigned long* iMethAddress = OutCast1[MethodNum - 1];
;--------------------------------------------------------
if (IsBadCodePtr($iMethAddress)) Then
$MethodNum -= 1
ExitLoop
Else
$MethodNum += 1
EndIf
WEnd
Return SetError(0,0,$MethodNum)
EndFunc

Func IsBadCodePtr($lpfn)
Local $iReturn
$iReturn = DllCall("Kernel32.dll","BOOL","IsBadCodePtr","ptr",$lpfn)
if @error Then Return SetError(1,0,0)
Return SetError(0,0,$iReturn[0])
EndFunc

Func GetObjFromGuid($dwClsContext,$StrIID,$StrCLSID)
$clsid = CLSIDFromString($StrCLSID)
if @error Then Return SetError(2,0,0)
$riid = IIDFromString($StrIID)
if @error Then Return SetError(3,0,0)
$Rt = DllCall($Ole32,"long","CoCreateInstance","ptr",DllStructGetPtr($clsid), _
"ptr",0,"DWORD",$dwClsContext,"ptr",DllStructGetPtr($riid),"ptr*",0)
if @error Or $Rt[0] <> 0 Then Return SetError(4,0,$Rt[0])
Return SetError(0,0,$Rt[5])
EndFunc

Func CoGetClassObject($rclsid,$dwClsContext,$pServerInfo,$riid)
$HRESULT = DllCall($Ole32,"long","CoGetClassObject","struct*",$rclsid, _
"DWORD",$dwClsContext,"ptr",$pServerInfo,"struct*",$riid,"ptr*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,$HRESULT[0])
Return SetError(0,0,$HRESULT[5])
EndFunc

Func CoRegisterClassObject($rclsid,$pUnk,$dwClsContext,$flags)
$HRESULT = DllCall($Ole32,"long","CoRegisterClassObject","struct*",$rclsid _
,"ptr",$pUnk,"DWORD",$dwClsContext,"DWORD",$flags,"DWORD*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,$HRESULT[0])
Return SetError(0,0,$HRESULT[5])
EndFunc

Func CoRegisterPSClsid($riid,$rclsid)
$HRESULT = DllCall($Ole32,"long","CoRegisterPSClsid","struct*",$riid,"struct*",$rclsid)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$HRESULT[0])
EndFunc

Func CoGetPSClsid($riid)
$HRESULT = DllCall($Ole32,"long","CoGetPSClsid","struct*",$riid,"ptr*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$HRESULT[2])
EndFunc

Func CoCreateGuid($ClipPut = False)
Local $nGUID = DllStructCreate($tagnGUID)
$HRESULT = DllCall($Ole32,"long","CoCreateGuid","struct*",$nGUID)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,0)
if ($ClipPut) Then ClipPut(_WinAPI_StringFromGUID($nGUID))
Return SetError(0,0,_WinAPI_StringFromGUID($nGUID))
EndFunc

Func RegisterActiveObject($punk,$rclsid,$dwFlags)
$HRESULT = DllCall($Ole32,"long","RegisterActiveObject","ptr",$punk _
,"struct*",$rclsid,"DWORD",$dwFlags,"DWORD*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$HRESULT[5])
EndFunc

Func CoRevokeClassObject($dwRegister)
$HRESULT = DllCall($Ole32,"long","CoRevokeClassObject","DWORD",$dwRegister)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,False)
Return SetError(0,0,True)
EndFunc

Func CoInitializeEx($pvReserved,$dwCoInit)
$HRESULT = DllCall($Ole32,"int","CoInitializeEx","ptr",$pvReserved,"DWORD",$dwCoInit)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,False)
Return SetError(0,0,True)
EndFunc

Func CLSIDFromString($psz)
Local $nGUID = DllStructCreate($tagnGUID)
$Oleerror = DllCall($Ole32,"int","CLSIDFromString","WSTR",$psz,"struct*",$nGUID)
if @error Or $Oleerror[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$nGUID)
EndFunc

Func IIDFromString($psz)
Local $nGUID = DllStructCreate($tagnGUID)
$Oleerror = DllCall($Ole32,"int","IIDFromString","WSTR",$psz,"struct*",$nGUID)
if @error Or $Oleerror[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$nGUID)
EndFunc

Func CLSIDFromProgID($psz)
Local $nGUID = DllStructCreate($tagnGUID)
$Oleerror = DllCall($Ole32,"int","CLSIDFromProgID","WSTR",$psz,"struct*",$nGUID)
if @error Or $Oleerror[0] <> 0 Then Return SetError(1,0,0)
Return SetError(0,0,$nGUID)
EndFunc

Func MIDL_DEFINE_GUID($Elm1,$Elm2,$Elm3,$iElm1,$iElm2,$iElm3,$iElm4,$iElm5,$iElm6,$iElm7,$iElm8)
$vGUID = DllStructCreate($tagnGUID)
DllStructSetData($vGUID,1,$Elm1)
DllStructSetData($vGUID,2,$Elm2)
DllStructSetData($vGUID,3,$Elm3)
DllStructSetData($vGUID,4,$iElm1,1)
DllStructSetData($vGUID,4,$iElm2,2)
DllStructSetData($vGUID,4,$iElm3,3)
DllStructSetData($vGUID,4,$iElm4,4)
DllStructSetData($vGUID,4,$iElm5,5)
DllStructSetData($vGUID,4,$iElm6,6)
DllStructSetData($vGUID,4,$iElm7,7)
DllStructSetData($vGUID,4,$iElm8,8)
Return $vGUID
EndFunc

DataType.au3

#include-once
#include "Constants.au3"

Func GetDataTypeNu($DataType,$SafeArray_vt = False) ;$SafeArray_vt See SafeArrayCreate Func

;http://msdn.microsoft.com/en-us/library/windows/desktop/ms683835%28v=vs.85%29.aspx
;There are two main types of servers, in-process and out-of-process. In-process servers are implemented in a
;dynamic linked library (DLL), and out-of-process servers are implemented in an executable file (EXE). Out-of-process
;servers can reside either on the local computer or on a remote computer. In addition, COM provides a mechanism that
;allows an in-process server (a DLL) to run in a surrogate EXE process to gain the advantage of being able to run the
;process on a remote computer. For more information, see DLL Surrogates.

;(in Exe Server) Ptr Of Proc Or Ptr Of Out Struct Not Allowed Only
;Ptr Of Data Type like (int* DllStructGetPtr(DllStructCreate("int")) ,SHORT* DllStructGetPtr(DllStructCreate("SHORT")) ) or
;((ARRAY A SAFEARRAY pointer),(DISPATCH pointer),(UNKNOWN pointer),(BSTR pointer)) Or
;Ptr Of VARIANT Struct Or Ptr Of DECIMAL Struct ; See code in thes Func

;VARIANT structure
;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627%28v=vs.85%29.aspx

;VARENUM enumeration
;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221170%28v=vs.85%29.aspx

Local $DataTypeNu , $VT_BYREF = 0x4000
Local $BOOLREF = (StringInStr($DataType,"*") <> 0)
$DataType = StringReplace(StringUpper($DataType),"*","")
Switch $DataType
Case "NONE"
$DataTypeNu = 24
Case "BYTE","BOOLEAN" ;Autoit BOOLEAN like BYTE 17
$DataTypeNu = 17
Case "SHORT"
$DataTypeNu = 2
Case "USHORT","WORD"
$DataTypeNu = 18
Case "INT","LONG","BOOL" ; Autoit BOOL like LONG 22
$DataTypeNu = 22
Case "UINT","ULONG","DWORD"
$DataTypeNu = 23
Case "INT64"
$DataTypeNu = 20
Case "UINT64"
$DataTypeNu = 21
Case "FLOAT"
$DataTypeNu = 4
Case "DOUBLE"
$DataTypeNu = 5


;---------------------------------------------------------------------------------------------
;_____________ C++ 6.0 wtypes.h  __________
;VT_I8 = 20
;VT_UI8 = 21
;VT_I4 = 3
;VT_UI4 = 19
;#ifdef _WIN64
;#define VT_INT_PTR  VT_I8
;#define VT_UINT_PTR VT_UI8
;#else
;#define VT_INT_PTR  VT_I4
;#define VT_UINT_PTR VT_UI4
;#endif
;_____________ C++ 6.0 wtypes.h  __________
; _WIN64 Macro Defined for applications for Win64.
;@AutoItX64 Returns 1 if the script is running under the native x64 version of AutoIt.
Case "HWND" ;32bit(4bytes) integer
$DataTypeNu = 3 ;VT_I4
Case "HANDLE" ;32bit(4bytes) integer
$DataTypeNu = 3 ;VT_I4
Case "LPARAM","INT_PTR","LONG_PTR","LRESULT" ;32 or 64bit signed integer
if (@AutoItX64) Then
$DataTypeNu = 20 ;VT_I8
Else
$DataTypeNu = 3 ;VT_I4
EndIf
Case "PTR","UINT_PTR","ULONG_PTR","DWORD_PTR","WPARAM";32 or 64bit unsigned integer
if (@AutoItX64) Then
$DataTypeNu = 21 ;VT_UI8
Else
$DataTypeNu = 19 ;VT_UI4
EndIf
;_____________ C++ 6.0 wtypes.h  __________
;VT_I8 = 20
;VT_UI8 = 21
;VT_I4 = 3
;VT_UI4 = 19
;#ifdef _WIN64
;#define VT_INT_PTR  VT_I8
;#define VT_UINT_PTR VT_UI8
;#else
;#define VT_INT_PTR  VT_I4
;#define VT_UINT_PTR VT_UI4
;#endif
;_____________ C++ 6.0 wtypes.h  __________
; _WIN64 Macro Defined for applications for Win64.
;@AutoItX64 Returns 1 if the script is running under the native x64 version of AutoIt
;---------------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------------
Case "VBOOL" ;VARIANT_BOOL short A 16-bit ;
;(C++ 6.0 wtypes.h typedef short VARIANT_BOOL) [in,out]  ([in] short) or ([out] short pointer (short*))
$DataTypeNu = 11
;---------------------------------------------------------------------------------------------

Case "BSTR" ;[in,out] See SysAllocString Func ([in] A BSTR pointer) or ([out] pointer* (Ptr*))
$DataTypeNu = 8
Case "VARIANT" ;pointer Of VARIANT structure ;[in,out] ([in,out] VARIANT pointer Only)
$DataTypeNu = 12
if Not($SafeArray_vt) Then $BOOLREF = True ; (Data Type Of VARIANT structure With ByRef Only)
;( Data Type Of $SafeArray_vt WithOut ByRef Only) See SafeArrayCreate Func

Case "ARRAY" ; A SAFEARRAY pointer [in,out] ([in] SAFEARRAY pointer) or ([out] pointer* (Ptr*))
$DataTypeNu = 0x2000

Case "DISPATCH" ;Interface [in,out] ([in] DISPATCH pointer) or ([out] pointer* (Ptr*))
$DataTypeNu = 9
Case "UNKNOWN" ;Interface [in,out] ([in] UNKNOWN pointer) or ([out] pointer* (Ptr*))
$DataTypeNu = 13
Case "DATE" ;DATE See GetDoubleTime Func [in,out]  ([in] double) or ([out] double pointer (double*))
$DataTypeNu = 7
Case "CY" ; Currency See GetCurrencyInt64 Func [in,out]  ([in] INT64) or ([out] INT64 pointer (INT64*))
$DataTypeNu = 6
Case "ERROR" ;Scode [in,out]  ([in] long) or ([out] long pointer (long*))
$DataTypeNu = 10
Case "DECIMAL" ;DECIMAL See GetDecimalSt Func / pointer Of DECIMAL structure ;[in,out] ([in,out] DECIMAL pointer Only)
$DataTypeNu = 14
if Not($SafeArray_vt) Then $BOOLREF = True ; (Data Type Of DECIMAL structure With ByRef Only)
;( Data Type Of $SafeArray_vt WithOut ByRef Only) See SafeArrayCreate Func
Case Else
Return SetError(1,0,-1)
EndSwitch

if ($BOOLREF) Then $DataTypeNu = BitOR($VT_BYREF,$DataTypeNu)
Return SetError(0,$BOOLREF,$DataTypeNu)

EndFunc

Func MakByRef($DataType = "ptr")
Return DllStructCreate(String($DataType & " ByRef"))
EndFunc

Func GetByRefValue($ByRefSt)
Return DllStructGetData($ByRefSt,1)
EndFunc

Func SetUnionOfVariant($VariantSt,$DataType,$Value)
Return DllStructSetData(DllStructCreate($DataType,DllStructGetPtr($VariantSt,"union")),1,$Value)
EndFunc

Func GetUnionOfVariant($VariantSt,$DataType)
Return DllStructGetData(DllStructCreate($DataType,DllStructGetPtr($VariantSt,"union")),1)
EndFunc

Func BstrToStr($BSTR,$FreeBstr = True)
$BstrLen = SysStringLen($BSTR)
if @error Then Return SetError(1,0,"")
$StringSt = DllStructCreate("WCHAR[" & ($BstrLen + 1) & "]",$BSTR)
$nString = DllStructGetData($StringSt,1)
if ($FreeBstr) Then SysFreeString($BSTR)
Return SetError(0,$BstrLen,$nString)
EndFunc

Func StrToBstr($String)
Return SetError(@error,0,SysAllocString($String))
EndFunc

Func SysAllocString($psz)
Local $DataType = "PTR"
if IsString($psz) Then $DataType = "WSTR"
$BSTR = DllCall($OleAut32,"ptr","SysAllocString",$DataType,$psz)
if @error Or $BSTR[0] = 0 Then Return SetError(1,0,0)
Return $BSTR[0] ;BSTR Ptr
EndFunc

Func SysStringLen($psz)
$UINT = DllCall($OleAut32,"UINT","SysStringLen","ptr",$psz)
if @error Then Return SetError(1,0,0)
Return $UINT[0]
EndFunc

Func SysFreeString($bstrString)
DllCall($OleAut32,"none","SysFreeString","ptr",$bstrString)
EndFunc

Func GetSystemTime($DoubleTime)
$lpSystemTime = DllStructCreate($vtagSYSTEMTIME)
$BOOL = DllCall($OleAut32,"int","VariantTimeToSystemTime","DOUBLE",$DoubleTime,"struct*",$lpSystemTime)
if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0)
Local $TimeArray[8][2]
$TimeArray[0][1] = "Year"
$TimeArray[0][0] = DllStructGetData($lpSystemTime,1)
$TimeArray[1][1] = "Month"
$TimeArray[1][0] = DllStructGetData($lpSystemTime,2)
$TimeArray[2][1] = "DayOfWeek"
$TimeArray[2][0] = DllStructGetData($lpSystemTime,3)
$TimeArray[3][1] = "Day"
$TimeArray[3][0] = DllStructGetData($lpSystemTime,4)
$TimeArray[4][1] = "Hour"
$TimeArray[4][0] = DllStructGetData($lpSystemTime,5)
$TimeArray[5][1] = "Minute"
$TimeArray[5][0] = DllStructGetData($lpSystemTime,6)
$TimeArray[6][1] = "Secon"
$TimeArray[6][0] = DllStructGetData($lpSystemTime,7)
$TimeArray[7][1] = "Milliseconds"
$TimeArray[7][0] = DllStructGetData($lpSystemTime,8)
Return $TimeArray
EndFunc

Func GetDoubleTime($wYear,$wMonth,$wDayOfWeek,$wDay,$wHour,$wMinute,$wSecond,$wMilliseconds)
$SYSTEMTIME = DllStructCreate($vtagSYSTEMTIME)
DllStructSetData($SYSTEMTIME,1,$wYear)
DllStructSetData($SYSTEMTIME,2,$wMonth)
DllStructSetData($SYSTEMTIME,3,$wDayOfWeek)
DllStructSetData($SYSTEMTIME,4,$wDay)
DllStructSetData($SYSTEMTIME,5,$wHour)
DllStructSetData($SYSTEMTIME,6,$wMinute)
DllStructSetData($SYSTEMTIME,7,$wSecond)
DllStructSetData($SYSTEMTIME,8,$wMilliseconds)
$BOOL = DllCall($OleAut32,"int","SystemTimeToVariantTime","struct*",$SYSTEMTIME,"DOUBLE*",0)
if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0)
$DoubleTime = $BOOL[2]
Return $DoubleTime
EndFunc

Func GetCurrencyInt64($Lo,$Hi)
$StCY = DllStructCreate($tagCY)
DllStructSetData($StCY,1,$Lo)
DllStructSetData($StCY,2,$Hi)
Return DllStructGetData(DllStructCreate("INT64",DllStructGetPtr($StCY)),1)
EndFunc

Func GetCurrencyStruct($Int64Value)
$Int64ValueSt = DllStructCreate("INT64")
DllStructSetData($Int64ValueSt,1,$Int64Value)
$TempStCY = DllStructCreate($tagCY,DllStructGetPtr($Int64ValueSt))
$StCY = DllStructCreate($tagCY)
DllStructSetData($StCY,1,DllStructGetData($TempStCY,1))
DllStructSetData($StCY,2,DllStructGetData($TempStCY,2))
Return $StCY
EndFunc

Func GetDecimalSt($scale,$sign,$Hi32,$Lo32,$Mid32)
$DEC = DllStructCreate($tagDEC)
DllStructSetData($DEC,2,$scale)
DllStructSetData($DEC,3,$sign)
DllStructSetData($DEC,4,$Hi32)
DllStructSetData($DEC,5,$Lo32)
DllStructSetData($DEC,6,$Mid32)
Return $DEC
EndFunc

Func SafeArrayCreate($DataType,$cElements,$lLbound = 0)
;Array Manipulation Functions
;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221145%28v=vs.85%29.aspx
$vt = GetDataTypeNu($DataType,True) ;True $SafeArray_vt
if @error Then Return SetError(1,0,0)
if (@extended or $vt = 0x2000) Then Return SetError(2,0,0) ;(@extended VT_BYREF) (0x2000 VT_ARRAY ==> SAFEARRAY Data Type Number)
$SAFEARRAY = DllCall($OleAut32,"ptr","SafeArrayCreate","USHORT",$vt,"UINT",1,"struct*",SABOUND($cElements,$lLbound))
if @error Or $SAFEARRAY[0] = 0 Then Return SetError(3,0,0)
Return $SAFEARRAY[0]
;$vt or $DataTypeNu
;The base type of the array (the VARTYPE of each element of the array). The VARTYPE is restricted to a subset of the
;variant types. Neither the VT_ARRAY nor the VT_BYREF flag can be set. VT_EMPTY and VT_NULL are not valid base types
;for the array. All other types are legal.
;cElements
;The number of elements in the dimension.
;lLbound
;The lower bound of the dimension.
EndFunc

Func SABOUND($cElements,$lLbound)
$SAFEARRAYBOUND = DllStructCreate($tagSAFEARRAYBOUND)
DllStructSetData($SAFEARRAYBOUND,1,$cElements)
DllStructSetData($SAFEARRAYBOUND,2,$lLbound)
Return $SAFEARRAYBOUND
EndFunc

TypeInfo.au3

#include <WinAPI.au3>
#include "DataType.au3"

Func CreateDispTypeInfo($Struidata)
$HRESULT = DllCall($OleAut32,"long","CreateDispTypeInfo","struct*",$Struidata,"DWORD",0,"ptr*",0)
if @error Or $HRESULT[0] <> 0 Then Return SetError(1,0,0)
$pptinfo = $HRESULT[3]
Return $pptinfo
EndFunc

Func MakeInterfacedata($cMembersCount)

if $cMembersCount < 1 Then Return SetError(1,0,0)
$AllocMethodData = GetAllocOfMethodsData($cMembersCount)
if @error Then Return SetError(2,0,0)
$StSize = DllStructGetSize(DllStructCreate($tagInterfacedata))
$LPVOID = CoTaskMemAlloc($StSize)
$InterfacedataSt = DllStructCreate($tagInterfacedata,$LPVOID)
DllStructSetData($InterfacedataSt,"MethodData",$AllocMethodData)
DllStructSetData($InterfacedataSt,"cMembers",$cMembersCount)

Return $InterfacedataSt
EndFunc

Func MakeMethodData(ByRef $InterfacedataSt,$MethodNumber,$MethodName,$ParametersCount,$ReturnType,$CALLCONV = $CC_STDCALL)

if ($MethodName == "") Or (Not IsString($MethodName)) Then Return SetError(1,0,False)
$vtReturn = GetDataTypeNu($ReturnType)
If @error Then Return SetError(2,0,False)

$cMembers = DllStructGetData($InterfacedataSt,"cMembers")
if $ParametersCount > 30 or $ParametersCount < 0 or $MethodNumber >  _
$cMembers Or $MethodNumber < 1 Then Return SetError(3,0,False)

$MethodsData = DllStructGetData($InterfacedataSt,"MethodData")
$MethodDataSt = GetStructOfMethodsData($MethodNumber,$MethodsData)
if @error Then Return SetError(4,0,False)

$MethodNameLen = StringLen($MethodName)
$AllocszName = AllocFromStruct("WCHAR[" & ($MethodNameLen + 1) & "]")
if @error Then Return SetError(5,0,False)
$szNameSt = StructFromAlloc($AllocszName,"WCHAR[" & ($MethodNameLen + 1) & "]")
if @error Then Return SetError(6,0,False)
DllStructSetData($szNameSt,1,$MethodName)

Local $ppdata = 0
if ($ParametersCount) Then $ppdata = GetAllocOfParamsData($ParametersCount)

DllStructSetData($MethodDataSt,"szName",$AllocszName) ; Alloc METHOD name
DllStructSetData($MethodDataSt,"ppdata",$ppdata) ; Alloc Parameters
DllStructSetData($MethodDataSt,"dispid",$MethodNumber) ; METHOD Id start from 1
DllStructSetData($MethodDataSt,"iMeth",($MethodNumber - 1)) ;The index of the method in the VTBL start from 0
DllStructSetData($MethodDataSt,"cc",$CALLCONV) ; calling convention
DllStructSetData($MethodDataSt,"cArgs",$ParametersCount) ; args for Parameters
DllStructSetData($MethodDataSt,"wFlags",$DISPATCH_METHOD) ; METHOD Flag
DllStructSetData($MethodDataSt,"vtReturn",$vtReturn) ;Number Of Return Type

Return True
EndFunc

Func MakeParamData(ByRef $InterfacedataSt,$MethodNumber, $ParamType1 = 0,$ParamName1 = 0,$ParamType2 = 0,$ParamName2 = 0, _
$ParamType3 = 0 ,$ParamName3 = 0 , $ParamType4 = 0 , $ParamName4 = 0 , $ParamType5 = 0 , $ParamName5 = 0,$ParamType6 = 0, _
$ParamName6 = 0 ,$ParamType7 = 0 ,$ParamName7 = 0, $ParamType8 = 0 , $ParamName8 = 0 , $ParamType9 = 0 , $ParamName9 = 0, _
$ParamType10 = 0 ,$ParamName10 = 0 ,$ParamType11= 0 ,$ParamName11= 0 ,$ParamType12= 0 , $ParamName12= 0 ,$ParamType13= 0, _
$ParamName13 = 0 ,$ParamType14 = 0 ,$ParamName14 = 0 ,$ParamType15= 0 ,$ParamName15= 0 , $ParamType16= 0,$ParamName16= 0, _
$ParamType17= 0 ,$ParamName17 = 0 ,$ParamType18 = 0 ,$ParamName18 = 0 ,$ParamType19= 0 ,$ParamName19= 0 ,$ParamType20= 0, _
$ParamName20= 0 ,$ParamType21= 0 ,$ParamName21 = 0 ,$ParamType22 = 0 ,$ParamName22 = 0 ,$ParamType23= 0 ,$ParamName23= 0, _
$ParamType24= 0 ,$ParamName24= 0 ,$ParamType25= 0 ,$ParamName25 = 0 ,$ParamType26 = 0 ,$ParamName26 = 0 ,$ParamType27= 0, _
$ParamName27= 0 , $ParamType28= 0 ,$ParamName28= 0 ,$ParamType29= 0 ,$ParamName29 = 0 ,$ParamType30 = 0,$ParamName30 = 0 )

Local $ParametersCount = ((@NumParams - 2)/2)
if (@NumParams > 2) And (Mod((@NumParams - 2),2) <> 0) Then Return SetError(1,0,False)

$cMembers = DllStructGetData($InterfacedataSt,"cMembers")
if $MethodNumber > $cMembers Or $MethodNumber < 1 Then Return SetError(2,0,False)

$MethodsData = DllStructGetData($InterfacedataSt,"MethodData")
$MethodDataSt = GetStructOfMethodsData($MethodNumber,$MethodsData)
if @error Then Return SetError(3,0,False)
$cArgs = DllStructGetData($MethodDataSt,"cArgs")
if ($cArgs <> $ParametersCount) Then Return SetError(4,0,False)
if $ParametersCount = 0 And $cArgs = 0 Then Return True

$ppdata = DllStructGetData($MethodDataSt,"ppdata")
; Test Loop
For $i = 1 To $ParametersCount
$ParamType = Eval("ParamType" & $i)
$ParamName = Eval("ParamName" & $i)
GetDataTypeNu($ParamType)
if @error Then Return SetError(5,0,False)
if ($ParamName == "" Or (Not IsString($ParamName))) Then Return SetError(6,0,False)
$ParamDataSt = GetStructOfParamsData($ppdata,$i)
if @error Then Return SetError(7,0,False)
Next

For $i = 1 To $ParametersCount
$ParamType = Eval("ParamType" & $i)
$ParamTypeNu = GetDataTypeNu($ParamType)
$ParamName = Eval("ParamName" & $i)
$ParamNameLen = StringLen($ParamName)
$AllocName = AllocFromStruct("WCHAR[" & ($ParamNameLen + 1) & "]")
$szNameSt = StructFromAlloc($AllocName,"WCHAR[" & ($ParamNameLen + 1) & "]")
DllStructSetData($szNameSt,1,$ParamName)
$ParamDataSt = GetStructOfParamsData($ppdata,$i)
DllStructSetData($ParamDataSt,"szName",$AllocName) ; Alloc Param name
DllStructSetData($ParamDataSt,"vt",$ParamTypeNu) ;Number Of Param Type
Next

Return True
EndFunc

Func GetAllocOfMethodsData($cMembers)
if $cMembers < 1 Then Return SetError(1,0,0)
$MethodsDataSize = (DllStructGetSize(DllStructCreate($tagMethodData)) * $cMembers)
if Not($MethodsDataSize) Then Return SetError(2,0,0)
$LPVOID = CoTaskMemAlloc($MethodsDataSize)
Return $LPVOID
EndFunc

Func GetStructOfMethodsData($MethodNumber,$ArrayhLock)
if $MethodNumber < 1 Then Return SetError(1,0,0)
$MethodDataSize = DllStructGetSize(DllStructCreate($tagMethodData))
$MethodsDataSt = DllStructCreate($tagMethodData,$ArrayhLock + ($MethodDataSize * ($MethodNumber - 1)))
if Not IsDllStruct($MethodsDataSt) Then Return SetError(2,0,0)
Return $MethodsDataSt
EndFunc

Func GetAllocOfParamsData($cArgs)
if $cArgs < 1 Then Return SetError(1,0,0)
$ParamsDataSize = (DllStructGetSize(DllStructCreate($tagParamData)) * $cArgs)
if Not($ParamsDataSize) Then Return SetError(2,0,0)
$LPVOID = CoTaskMemAlloc($ParamsDataSize)
Return $LPVOID
EndFunc

Func GetStructOfParamsData($ArrayhLock,$ParamNumber)
if $ParamNumber < 1 Then Return SetError(1,0,0)
$ParamDataSize = DllStructGetSize(DllStructCreate($tagParamData))
$ParamsDataSt = DllStructCreate($tagParamData,$ArrayhLock + ($ParamDataSize * ($ParamNumber - 1)))
if Not IsDllStruct($ParamsDataSt) Then Return SetError(2,0,0)
Return $ParamsDataSt
EndFunc

Func AllocFromStruct($tagSt)
$StSize = DllStructGetSize(DllStructCreate($tagSt))
if Not ($StSize) Then Return SetError(1,0,0)
$LPVOID = CoTaskMemAlloc($StSize)
Return $LPVOID
EndFunc

Func StructFromAlloc($hLock,$tagSt)
$NewSt = DllStructCreate($tagSt,$hLock)
if Not IsDllStruct($NewSt) Then Return SetError(1,0,0)
Return $NewSt
EndFunc

Func CoTaskMemAlloc($cb)
$LPVOID = DllCall($Ole32,"ptr","CoTaskMemAlloc","int",$cb)
if @error Or $LPVOID[0] = 0 Then Return SetError(1,0,0)
Return $LPVOID[0]
EndFunc

Func CoTaskMemFree($pv)
DllCall($Ole32,"NONE","CoTaskMemFree","ptr",$pv)
EndFunc

Constants.au3

#include-once
#include <WinAPI.au3>

Global $Ole32 = DllOpen("Ole32.dll")
Global $OleAut32 = DllOpen("OleAut32.dll")
Global $Kernel32 = DllOpen("Kernel32.dll")
Global $tagVariant = "USHORT vt;WORD wReserved1;WORD wReserved2;WORD wReserved3;byte union[8]"
Global $tagDISPPARAMS = "ptr rgvarg;ptr rgdispidNamedArgs;UINT cArgs;UINT cNamedArgs"
Global $tagMethodData = "ptr szName;ptr ppdata;UINT dispid;UINT iMeth;UINT cc;UINT cArgs;WORD wFlags;WORD vtReturn;"
Global $tagParamData = "ptr szName;WORD vt;"
Global $tagInterfacedata = "ptr MethodData;UINT cMembers"
Global $vtagSYSTEMTIME = "WORD wYear;WORD wMonth;WORD wDayOfWeek;WORD wDay;WORD wHour;WORD wMinute;" & _
"WORD wSecond;WORD wMilliseconds"
Global $tagCY = "ULONG Lo;long Hi"
Global $tagDEC  = "USHORT wReserved;BYTE scale;BYTE sign;ULONG Hi32;ULONG Lo32;ULONG Mid32;"
Global $tagSAFEARRAYBOUND = "ULONG cElements;LONG lLbound"
Global $tagnGUID = "ulong Data1;ushort Data2;ushort Data3;byte Data4[8]"
Global $VariantSize = DllStructGetSize(DllStructCreate($tagVariant))
Global $SizeOfUlong_Ptr = DllStructGetSize(DllStructCreate("ULONG_PTR"))
Global $IID_NULL = DllStructCreate("ulong Data1;ushort Data2;ushort Data3;byte Data4[8]")
Global $StOfClassArray[1][4]

; flags for RegisterActiveObject
Global $ACTIVEOBJECT_STRONG = 0x0
Global $ACTIVEOBJECT_WEAK = 0x1

;wFlags MemberType
Global $DISPATCH_METHOD = 0x1, _
$DISPATCH_PROPERTYGET = 0x2 , _
$DISPATCH_PROPERTYPUT = 0x4 , _
$DISPATCH_PROPERTYPUTREF = 0x8
;wFlags MemberType
;enum $tagCALLCONV
Global $CC_FASTCALL = 0
Global $CC_CDECL = 1
Global $CC_MSCPASCAL = $CC_CDECL + 1
Global $CC_PASCAL = $CC_MSCPASCAL
Global $CC_MACPASCAL = $CC_PASCAL + 1
Global $CC_STDCALL = $CC_MACPASCAL + 1
Global $CC_FPFASTCALL = $CC_STDCALL + 1
Global $CC_SYSCALL = $CC_FPFASTCALL + 1
Global $CC_MPWCDECL = $CC_SYSCALL + 1
Global $CC_MPWPASCAL = $CC_MPWCDECL + 1
Global $CC_MAX = $CC_MPWPASCAL + 1
;enum $tagCALLCONV

;tagCLSCTX
;$dwClsContext
Global $CLSCTX_INPROC_SERVER=0x1 , _
$CLSCTX_INPROC_HANDLER=0x2 , _
$CLSCTX_LOCAL_SERVER=0x4 , _
$CLSCTX_INPROC_SERVER16=0x8 , _
$CLSCTX_REMOTE_SERVER=0x10 , _
$CLSCTX_INPROC_HANDLER16=0x20 , _
$CLSCTX_RESERVED1=0x40 , _
$CLSCTX_RESERVED2=0x80 , _
$CLSCTX_RESERVED3=0x100 , _
$CLSCTX_RESERVED4=0x200 , _
$CLSCTX_NO_CODE_DOWNLOAD=0x400 , _
$CLSCTX_RESERVED5=0x800 , _
$CLSCTX_NO_CUSTOM_MARSHAL=0x1000 , _
$CLSCTX_ENABLE_CODE_DOWNLOAD=0x2000 , _
$CLSCTX_NO_FAILURE_LOG=0x4000 , _
$CLSCTX_DISABLE_AAA=0x8000 , _
$CLSCTX_ENABLE_AAA=0x10000 , _
$CLSCTX_FROM_DEFAULT_CONTEXT=0x20000 , _
$CLSCTX_ACTIVATE_32_BIT_SERVER=0x40000 , _
$CLSCTX_ACTIVATE_64_BIT_SERVER=0x80000 , _
$CLSCTX_ENABLE_CLOAKING=0x100000 , _
$CLSCTX_APPCONTAINER=0x400000 , _
$CLSCTX_ACTIVATE_AAA_AS_IU=0x800000 , _
$CLSCTX_PS_DLL=0x80000000
;$dwClsContext
;tagCLSCTX

;tagREGCLS
;flags
Global $REGCLS_SINGLEUSE = 0, _
$REGCLS_MULTIPLEUSE = 1, _
$REGCLS_MULTI_SEPARATE = 2, _
$REGCLS_SUSPENDED = 4, _
$REGCLS_SURROGATE = 8
;flags
;tagREGCLS
Edited by wolf9228
1 person likes this

صرح السماء كان هنا

 

Share this post


Link to post
Share on other sites



Nice !

Good work Wolf :thumbsup:

Share this post


Link to post
Share on other sites

Nice !

Good work Wolf :thumbsup:

 

Thank you MsgBox :)


صرح السماء كان هنا

 

Share this post


Link to post
Share on other sites

Gorgeous as Usual!

Share this post


Link to post
Share on other sites

Gorgeous as Usual!

 

Thank you :)


صرح السماء كان هنا

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0