Jump to content
Sign in to follow this  
wolf9228

Exe server (IDispatch Call)

Recommended Posts

wolf9228

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
  • Like 1

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

 

Share this post


Link to post
Share on other sites
wolf9228

Nice !

Good work Wolf :thumbsup:

 

Thank you MsgBox :)


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

 

Share this post


Link to post
Share on other sites
wolf9228

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.