DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 69#p180569
==================================================
[Update 2:] Overhaul of function, see this post:
DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 12#p173112
==================================================
[Update 1:] This release was intended as a beta version that might benefit some people until I fully finish this. Do double-check code before/after, e.g. with WinMerge to make sure that it has converted it correctly, one problem that has emerged is incorrectly adding a final parameter type (sometimes the script *should* add in a return type, sometimes it shouldn't). [EDIT: This has now been fixed, see the lines marked 'EDIT'.]
This is my first attempt at a script that automatically converts (and cleans) DllCall lines from x32 to x64/x32 two-way compatible.
Note that in this example for COM.ahk, it won't make the script itself work in x64, as 'NumGet' lines, and 'DllCall(NumGet' lines are not fixed by the script.
This is quite a complex task to attempt, so do double check everything with a tool such as WinMerge to check that the conversion has worked correctly. This script is quite fiddly, and for example, I'm not certain that it can correctly handle consecutive double quotes in strings yet. Also, it doesn't yet handle the `" notation in AHK v2.
Be aware that it is not yet intended to anticipate all possible parsing issues, but to be good enough for most likely circumstances, with tweaking if necessary.
Btw this gives: '"Type", Arg, "Type", Arg' style, even though I happen to prefer 'Type,Arg, Type,Arg' style. The script could be modified in future to support such a preference.
Do notify of any issues.
Code: Select all
;e.g. script to convert
;COM.AHK/com.ahk at master · ttnnkkrr/COM.AHK · GitHub
;https://github.com/ttnnkkrr/COM.AHK/blob/master/com.ahk
;q:: ;convert DllCall lines (make them x64/x32 two-way compatible)
vDoMsgBoxBeforeAfter := 0
;STAGE - prepare list of dll functions + parameters
vListDllFunc = ;continuation section
(
atl\AtlAxAttachControl=ttt(i)
atl\AtlAxCreateControl=tttt(i)
atl\AtlAxGetControl=tt(i)
atl\AtlAxGetHost=tt(i)
atl\AtlAxWinInit=(i)
kernel32\FormatMessage=uituiuituit(ui)
kernel32\LoadLibrary=t(t)
kernel32\lstrcpyW=tt(t)
kernel32\RtlMoveMemory=ttut(i)
ole32\CLSIDFromProgID=tt(i)
ole32\CLSIDFromString=tt(i)
ole32\CoCreateGuid=t(i)
ole32\CoCreateInstance=ttuitt(i)
ole32\CoGetObject=tttt(i)
ole32\CoInitialize=t(i)
ole32\CoTaskMemAlloc=ut(t)
ole32\CoTaskMemFree=t(i)
ole32\CoUninitialize=(i)
ole32\IsEqualGUID=tt(i)
ole32\OleInitialize=t(i)
ole32\OleUninitialize=(i)
ole32\ProgIDFromCLSID=tt(i)
ole32\StringFromGUID2=tti(i)
oleacc\AccessibleChildren=tiitt(i)
oleacc\AccessibleObjectFromEvent=tuiuitt(i)
oleacc\AccessibleObjectFromPoint=ui6tt(i)
oleacc\AccessibleObjectFromWindow=tuitt(i)
oleacc\GetRoleTextW=uitui(ui)
oleacc\GetStateTextW=uitui(ui)
oleacc\WindowFromAccessibleObject=tt(i)
oleaut32\DispGetParam=tuiuhtt(i)
oleaut32\GetActiveObject=ttt(i)
oleaut32\SafeArrayDestroy=t(i)
oleaut32\SysAllocString=t(t)
oleaut32\SysFreeString=t(i)
oleaut32\VariantChangeTypeEx=ttuiuhuh(i)
oleaut32\VariantClear=t(i)
user32\CreateWindowEx=uittuiiiiitttt(t)
user32\GetParent=t(t)
)
oDllInfo := {}
Loop, Parse, vListDllFunc, `n
{
oTemp := StrSplit(A_LoopField, "=")
oDllInfo[oTemp.1] := oTemp.2
}
;STAGE - load script to be converted (+ do any custom replacements)
vPath = %A_Desktop%\COM.ahk
;vPath = %A_Desktop%\COM x64 2.ahk
if !FileExist(vPath)
{
MsgBox, % "error: file not found:`r`n" vPath
return
}
SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
if vName contains COM
vName := "COM.ahk"
FileRead, vText, % vPath
vTextOrig := vText
vBarrier := "=================================================="
vBarrier2 := "`r`n" vBarrier "`r`n"
vIsV1 := !!SubStr(1,0)
vList := "Ptr,Int64,Int,Short,Char,Float,Double"
vListU := "UPtr,UInt64,UInt,UShort,UChar"
vListP := "PtrP,Int64P,IntP,ShortP,CharP,FloatP,DoubleP"
vListPU := "UPtrP,UInt64P,UIntP,UShortP,UCharP"
vListA := "Ptr*,Int64*,Int*,Short*,Char*,Float*,Double*"
vListAU := "UPtr*,UInt64*,UInt*,UShort*,UChar*"
vListS := "Str,AStr,WStr"
vListPtr := vListP "," vListPU "," vListA "," vListAU "," vListS
vListAll := vList "," vListU "," vListPtr
if (vName = "COM.ahk")
{
;AccessibleObjectFromPoint: has 1 POINT parameter, not 2 (x and y) parameters
vNeedle = "oleacc\AccessibleObjectFromPoint", "int", x, "int", y
vReplaceText = "oleacc\AccessibleObjectFromPoint", "int64", x&0xFFFFFFFF|y<<32
vText := StrReplace(vText, vNeedle, vReplaceText)
}
;vUnused := JEE_StrGetUnusedChar1Var(vText)
vUnused := Chr(1)
;STAGE - find each occurrence of DllCall and convert it
Loop
{
vOcc := A_Index
vPos := InStr(vText, "DllCall(", 0, 1, vOcc)
if !vPos
break
vTempX := SubStr(vText, vPos, 60)
vPosOrig := vPos, vPos := vPos+7
;STAGE - find the end of the DllCall line + count the parameters
;issues this script attempts to handle:
;opening/closing double quotes/brackets
;consecutive double quotes in strings
;functions within functions
vDepth := 0
oCommaCount := {}, oQuoteCount := {}, oInQuote := {}
vTemp := "DllCall", vTemp2 := "DllCall"
Loop
{
vChar := SubStr(vText, vPos, 1)
vPos++
if (vChar = Chr(34))
oInQuote[vDepth] := !oInQuote[vDepth], oQuoteCount[vDepth]++
if (vCharLast = Chr(34))
&& !(oQuoteCount[vDepth] & 1) && !(vChar = Chr(34))
oInQuote[vDepth] := 0
if (vChar = "(") && !oInQuote[vDepth]
vDepth++
if (vChar = ")") && !oInQuote[vDepth]
vDepth--
if (vChar = ",") && !oInQuote[vDepth]
oCommaCount[vDepth] := oCommaCount[vDepth] ? oCommaCount[vDepth]+1 : 1
vTemp .= vChar
if (vChar = ",") && (vDepth = 1) && !oInQuote[1]
vTemp2 .= vUnused
else
vTemp2 .= vChar
if !vDepth
break
vCharLast := vChar
}
vLen := StrLen(vTemp2)
vTempOrig := vTemp
if (SubStr(vTemp2, vIsV1-1) = ")")
vTemp2 := SubStr(vTemp2, 1, -1)
oTemp := StrSplit(vTemp2, vUnused)
vCountParam := oTemp.MaxIndex()
;STAGE - get parameters for dll function, add return type parameter if needed
vTempX := oTemp.1
if (SubStr(vTempX, 1, 8) = "DllCall(")
vTempX := SubStr(vTempX, 9)
if (SubStr(vTempX, 1, 7) = "NumGet(")
continue
;custom replacement to handle lines that start: DllCall("atl" . Version
vNeedle = " . Version . "
vTempX := StrReplace(vTempX, vNeedle, "")
if (SubStr(vTempX, 1, 1) = """") && (SubStr(vTempX, vIsV1-1) = """")
vTempX := SubStr(vTempX, 2, -1)
vValue := oDllInfo[vTempX]
if (vValue = "")
{
MsgBox, % "error: dll function parameters not defined:`r`n" vTempOrig
return
}
oList := JEE_DllParamListExpand(vValue, vCount, vCountX)
vCount1 := vCount+vCount
vCount2 := vCount+vCountX
;if !(vCount+vCountX = vCountParam) ;EDIT
if (vCount+vCountX = vCountParam) ;EDIT
&& !(oList[oList.MaxIndex()] = "Int")
oTemp[oTemp.MaxIndex()+1] := oList[oList.MaxIndex()]
;STAGE - convert parameter types
vIndexParam := 1
Loop, % oTemp.MaxIndex()
{
vTemp := Trim(oTemp[A_Index])
if (A_Index = 1)
continue
if (A_Index & 1) ;A_Index is an odd number
{
oTemp[A_Index] := " " vTemp
continue
}
vTemp := Trim(vTemp, """")
vTemp := StrReplace(vTemp, " " , "")
vParam := oList[vIndexParam]
vParamOrig := vTemp
vTemp := vParam
if vTemp in Ptr
if vParamOrig in %vListPtr%
vTemp := vParamOrig
vIsMatch := 0
Loop, Parse, vListAll, % ","
if (vTemp = A_LoopField)
vTemp := A_LoopField, vIsMatch := 1
if !vIsMatch
{
MsgBox, % "error: unrecognised parameter type:`r`n" vTemp2 vBarrier2 vParamOrig
return
}
oTemp[A_Index] := " """ vTemp """"
vIndexParam++
}
vTemp := ""
Loop, % oTemp.MaxIndex()-1
vTemp .= oTemp[A_Index] ","
vTemp .= oTemp[oTemp.MaxIndex()]
vTemp .= ")"
vText := SubStr(vText, 1, vPosOrig-1) vTemp SubStr(vText, vPosOrig+vLen)
if vDoMsgBoxBeforeAfter
MsgBox, % "before/after:`r`n`r`n" vTempOrig "`r`n`r`n" vTemp
oCommaCount := oQuoteCount := oInQuote := ""
}
oDllInfo := oList := oTemp := ""
;JEE_WinMergeCompareStrings(vTextOrig, vText " ")
Clipboard := vText
MsgBox, % "done"
return
;==================================================
;notation based on:
;WinApi
;https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
;note: replaced 'i6:Int64', with '6:Int64' in the array
;vCount is the number of parameters
;vCountX is the number of parameters if you omit a return type of Int
JEE_DllParamListExpand(vText, ByRef vCount="", ByRef vCountX="")
{
static oArray := {i:"Int",s:"Str",a:"AStr",w:"WStr",h:"Short",c:"Char",f:"Float",d:"Double",t:"Ptr",6:"Int64"}
vText := StrReplace(vText, "i6", "6")
vText := StrReplace(vText, "(", "")
vText := StrReplace(vText, ")", "")
Loop, Parse, vText
vOutput .= (A_LoopField = "u") ? "U" : oArray[A_LoopField] ","
vOutput := SubStr(vOutput, 1, -1)
oList := StrSplit(vOutput, ",")
oList.Summary := vOutput
vCount := oList.Length()
vCountX := oList.Length()-1
return oList
}
;==================================================
Code: Select all
;------------------------------------------------------------------------------
; COM.ahk Standard Library
; by Sean
; http://www.autohotkey.com/forum/topic22923.html
;------------------------------------------------------------------------------
COM_Init(bUn = "")
{
Static h
Return (bUn&&!h:="")||h==""&&1==(h:=DllCall("ole32\OleInitialize", "Ptr", 0))?DllCall("ole32\OleUninitialize"):0
}
COM_Term()
{
COM_Init(1)
}
COM_VTable(ppv, idx)
{
Return NumGet(NumGet(1*ppv)+4*idx)
}
COM_QueryInterface(ppv, IID = "")
{
If DllCall(NumGet(NumGet(1*ppv:=COM_Unwrap(ppv))), "Uint", ppv+0, "Uint", COM_GUID4String(IID,IID ? IID:IID=0 ? "{00000000-0000-0000-C000-000000000046}":"{00020400-0000-0000-C000-000000000046}"), "UintP", ppv:=0)=0
Return ppv
}
COM_AddRef(ppv)
{
Return DllCall(NumGet(NumGet(1*ppv:=COM_Unwrap(ppv))+4), "Uint", ppv)
}
COM_Release(ppv)
{
If Not IsObject(ppv)
Return DllCall(NumGet(NumGet(1*ppv)+8), "Uint", ppv)
Else
{
nRef:= DllCall(NumGet(NumGet(COM_Unwrap(ppv))+8), "Uint", COM_Unwrap(ppv)), nRef==0 ? (ppv.prm_:=0):""
Return nRef
}
}
COM_QueryService(ppv, SID, IID = "")
{
If DllCall(NumGet(NumGet(1*ppv:=COM_Unwrap(ppv))), "Uint", ppv, "Uint", COM_GUID4String(IID_IServiceProvider,"{6D5140C1-7436-11CE-8034-00AA006009FA}"), "UintP", psp)=0
&& DllCall(NumGet(NumGet(1*psp)+12), "Uint", psp, "Uint", COM_GUID4String(SID,SID), "Uint", IID ? COM_GUID4String(IID,IID):&SID, "UintP", ppv:=0)+DllCall(NumGet(NumGet(1*psp)+8), "Uint", psp)*0=0
Return COM_Enwrap(ppv)
}
COM_FindConnectionPoint(pdp, DIID)
{
DllCall(NumGet(NumGet(1*pdp)+ 0), "Uint", pdp, "Uint", COM_GUID4String(IID_IConnectionPointContainer, "{B196B284-BAB4-101A-B69C-00AA00341D07}"), "UintP", pcc)
DllCall(NumGet(NumGet(1*pcc)+16), "Uint", pcc, "Uint", COM_GUID4String(DIID,DIID), "UintP", pcp)
DllCall(NumGet(NumGet(1*pcc)+ 8), "Uint", pcc)
Return pcp
}
COM_GetConnectionInterface(pcp)
{
VarSetCapacity(DIID,16,0)
DllCall(NumGet(NumGet(1*pcp)+12), "Uint", pcp, "Uint", &DIID)
Return COM_String4GUID(&DIID)
}
COM_Advise(pcp, psink)
{
DllCall(NumGet(NumGet(1*pcp)+20), "Uint", pcp, "Uint", psink, "UintP", nCookie)
Return nCookie
}
COM_Unadvise(pcp, nCookie)
{
Return DllCall(NumGet(NumGet(1*pcp)+24), "Uint", pcp, "Uint", nCookie)
}
COM_Enumerate(penum, ByRef Result, ByRef vt = "")
{
VarSetCapacity(varResult,16,0)
If (0 = hr:=DllCall(NumGet(NumGet(1*penum:=COM_Unwrap(penum))+12), "Uint", penum, "Uint", 1, "Uint", &varResult, "UintP", 0))
Result:=(vt:=NumGet(varResult,0,"Ushort"))=9||vt=13?COM_Enwrap(NumGet(varResult,8),vt):vt=8||vt<0x1000&&COM_VariantChangeType(&varResult,&varResult)=0?StrGet(NumGet(varResult,8)) . COM_VariantClear(&varResult):NumGet(varResult,8)
Return hr
}
COM_Invoke(pdsp,name="",prm0="vT_NoNe",prm1="vT_NoNe",prm2="vT_NoNe",prm3="vT_NoNe",prm4="vT_NoNe",prm5="vT_NoNe",prm6="vT_NoNe",prm7="vT_NoNe",prm8="vT_NoNe",prm9="vT_NoNe")
{
pdsp := COM_Unwrap(pdsp)
If name=
Return DllCall(NumGet(NumGet(1*pdsp)+8),"Uint",pdsp)
If name contains .
{
SubStr(name,1,1)!="." ? name.=".":name:=SubStr(name,2) . "."
Loop, Parse, name, .
{
If A_Index=1
{
name := A_LoopField
Continue
}
Else If name not contains [,(
prmn := ""
Else If InStr("])",SubStr(name,0))
Loop, Parse, name, [(,'")]
If A_Index=1
name := A_LoopField
Else prmn := A_LoopField
Else
{
name .= "." . A_LoopField
Continue
}
If A_LoopField!=
pdsp:= COM_Invoke(pdsp,name,prmn!="" ? prmn:"vT_NoNe"),name:=A_LoopField
Else Return prmn!=""?COM_Invoke(pdsp,name,prmn,prm0,prm1,prm2,prm3,prm4,prm5,prm6,prm7,prm8):COM_Invoke(pdsp,name,prm0,prm1,prm2,prm3,prm4,prm5,prm6,prm7,prm8,prm9)
}
}
Static varg,namg,iidn,varResult,sParams
VarSetCapacity(varResult,64,0),sParams?"":(sParams:="0123456789",VarSetCapacity(varg,160,0),VarSetCapacity(namg,88,0),VarSetCapacity(iidn,16,0)),mParams:=0,nParams:=10,nvk:=3
Loop, Parse, sParams
If (prm%A_LoopField%=="vT_NoNe")
{
nParams:=A_Index-1
Break
}
Else If prm%A_LoopField% is integer
NumPut(SubStr(prm%A_LoopField%,1,1)="+"?9:prm%A_LoopField%=="-0"?(prm%A_LoopField%:=0x80020004)*0+10:3,NumPut(prm%A_LoopField%,varg,168-16*A_Index),-12)
Else If IsObject(prm%A_LoopField%)
typ:=prm%A_LoopField%["typ_"],prm:=prm%A_LoopField%["prm_"],typ+0==""?(NumPut(&_nam_%A_LoopField%:=typ,namg,84-4*mParams++),typ:=prm%A_LoopField%["nam_"]+0==""?prm+0==""||InStr(prm,".")?8:3:prm%A_LoopField%["nam_"]):"",NumPut(typ==8?COM_SysString(prm%A_LoopField%,prm):prm,NumPut(typ,varg,160-16*A_Index),4)
Else NumPut(COM_SysString(prm%A_LoopField%,prm%A_LoopField%),NumPut(8,varg,160-16*A_Index),4)
If nParams
SubStr(name,0)="="?(name:=SubStr(name,1,-1),nvk:=12,NumPut(-3,namg,4)):"",NumPut(nvk==12?1:mParams,NumPut(nParams,NumPut(&namg+4,NumPut(&varg+160-16*nParams,varResult,16))))
Global COM_HR, COM_LR:=""
If (COM_HR:=DllCall(NumGet(NumGet(1*pdsp)+20),"Uint",pdsp,"Uint",&iidn,"Uint",NumPut(&name,namg,84-4*mParams)-4,"Uint",1+mParams,"Uint",1024,"Uint",&namg,"Uint"))=0&&(COM_HR:=DllCall(NumGet(NumGet(1*pdsp)+24),"Uint",pdsp,"int",NumGet(namg),"Uint",&iidn,"Uint",1024,"Ushort",nvk,"Uint",&varResult+16,"Uint",&varResult,"Uint",&varResult+32,"Uint",0,"Uint"))!=0&&nParams&&nvk<4&&NumPut(-3,namg,4)&&(COM_LR:=DllCall(NumGet(NumGet(1*pdsp)+24),"Uint",pdsp,"int",NumGet(namg),"Uint",&iidn,"Uint",1024,"Ushort",12,"Uint",NumPut(1,varResult,28)-16,"Uint",0,"Uint",0,"Uint",0,"Uint"))=0
COM_HR:=0
Global COM_VT:=NumGet(varResult,0,"Ushort")
Return COM_HR=0?COM_VT>1?COM_VT=9||COM_VT=13?COM_Enwrap(NumGet(varResult,8),COM_VT):COM_VT=8||COM_VT<0x1000&&COM_VariantChangeType(&varResult,&varResult)=0?StrGet(NumGet(varResult,8)) . COM_VariantClear(&varResult):NumGet(varResult,8):"":COM_Error(COM_HR,COM_LR,&varResult+32,name)
}
COM_InvokeSet(pdsp,name,prm0,prm1="vT_NoNe",prm2="vT_NoNe",prm3="vT_NoNe",prm4="vT_NoNe",prm5="vT_NoNe",prm6="vT_NoNe",prm7="vT_NoNe",prm8="vT_NoNe",prm9="vT_NoNe")
{
Return COM_Invoke(pdsp,name "=",prm0,prm1,prm2,prm3,prm4,prm5,prm6,prm7,prm8,prm9)
}
COM_DispInterface(this, prm1="", prm2="", prm3="", prm4="", prm5="", prm6="", prm7="", prm8="")
{
Critical
If A_EventInfo = 6
hr:=DllCall(NumGet(NumGet(0+p:=NumGet(this+8))+28),"Uint",p,"Uint",prm1,"UintP",pname,"Uint",1,"UintP",0),hr==0?(sfn:=StrGet(this+40) . StrGet(pname),COM_SysFreeString(pname),%sfn%(prm5,this,prm6)):""
Else If A_EventInfo = 5
hr:=DllCall(NumGet(NumGet(0+p:=NumGet(this+8))+40),"Uint",p,"Uint",prm2,"Uint",prm3,"Uint",prm5)
Else If A_EventInfo = 4
NumPut(0*hr:=0x80004001,prm3+0)
Else If A_EventInfo = 3
NumPut(0,prm1+0)
Else If A_EventInfo = 2
NumPut(hr:=NumGet(this+4)-1,this+4)
Else If A_EventInfo = 1
NumPut(hr:=NumGet(this+4)+1,this+4)
Else If A_EventInfo = 0
COM_IsEqualGUID(this+24,prm1)||InStr("{00020400-0000-0000-C000-000000000046}{00000000-0000-0000-C000-000000000046}",COM_String4GUID(prm1)) ? NumPut(NumPut(NumGet(this+4)+1,this+4)-8,prm2+0):NumPut(0*hr:=0x80004002,prm2+0)
Return hr
}
COM_DispGetParam(pDispParams, Position = 0, vt = 8)
{
VarSetCapacity(varResult,16,0)
DllCall("oleaut32\DispGetParam", "Ptr", pDispParams, "UInt", Position, "UShort", vt, "Ptr", &varResult, "UIntP", nArgErr)
Return (vt:=NumGet(varResult,0,"Ushort"))=8?StrGet(NumGet(varResult,8)) . COM_VariantClear(&varResult):vt=9||vt=13?COM_Enwrap(NumGet(varResult,8),vt):NumGet(varResult,8)
}
COM_DispSetParam(val, pDispParams, Position = 0, vt = 8)
{
Return NumPut(vt=8?COM_SysAllocString(val):vt=9||vt=13?COM_Unwrap(val):val,NumGet(NumGet(pDispParams+0)+(NumGet(pDispParams+8)-Position)*16-8),0,vt=11||vt=2 ? "short":"int")
}
COM_Error(hr = "", lr = "", pei = "", name = "")
{
Static bDebug:=1
If Not pei
{
bDebug:=hr
Global COM_HR, COM_LR
Return COM_HR&&COM_LR ? COM_LR<<32|COM_HR:COM_HR
}
Else If !bDebug
Return
hr ? (VarSetCapacity(sError,1022),VarSetCapacity(nError,62),DllCall("kernel32\FormatMessage", "UInt", 0x1200, "Ptr", 0, "UInt", hr<>0x80020009?hr:(bExcep:=1)*(hr:=NumGet(pei+28))?hr:hr:=NumGet(pei+0,0,"Ushort")+0x80040200, "UInt", 0, "Str", sError, "UInt", 512, "Ptr", 0, "UInt"),DllCall("kernel32\FormatMessage", "UInt", 0x2400, "Str", "0x%1!p!", "UInt", 0, "UInt", 0, "Str", nError, "UInt", 32, "UIntP", hr, "UInt")):sError:="No COM Dispatch Object!`n",lr?(VarSetCapacity(sError2,1022),VarSetCapacity(nError2,62),DllCall("kernel32\FormatMessage", "UInt", 0x1200, "Ptr", 0, "UInt", lr, "UInt", 0, "Str", sError2, "UInt", 512, "Ptr", 0, "UInt"),DllCall("kernel32\FormatMessage", "UInt", 0x2400, "Str", "0x%1!p!", "UInt", 0, "UInt", 0, "Str", nError2, "UInt", 32, "UIntP", lr, "UInt")):""
MsgBox, 260, COM Error Notification, % "Function Name:`t""" . name . """`nERROR:`t" . sError . "`t(" . nError . ")" . (bExcep ? SubStr(NumGet(pei+24) ? DllCall(NumGet(pei+24),"Uint",pei) : "",1,0) . "`nPROG:`t" . StrGet(NumGet(pei+4)) . COM_SysFreeString(NumGet(pei+4)) . "`nDESC:`t" . StrGet(NumGet(pei+8)) . COM_SysFreeString(NumGet(pei+8)) . "`nHELP:`t" . StrGet(NumGet(pei+12)) . COM_SysFreeString(NumGet(pei+12)) . "," . NumGet(pei+16) : "") . (lr ? "`n`nERROR2:`t" . sError2 . "`t(" . nError2 . ")" : "") . "`n`nWill Continue?"
IfMsgBox, No, Exit
}
COM_CreateIDispatch()
{
Static IDispatch
If Not VarSetCapacity(IDispatch)
{
VarSetCapacity(IDispatch,28,0), nParams=3112469
Loop, Parse, nParams
NumPut(RegisterCallback("COM_DispInterface","",A_LoopField,A_Index-1),IDispatch,4*(A_Index-1))
}
Return &IDispatch
}
COM_GetDefaultInterface(pdisp)
{
DllCall(NumGet(NumGet(1*pdisp) +12), "Uint", pdisp , "UintP", ctinf)
If ctinf
{
DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint" , 0, "Uint", 1024, "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
DllCall(NumGet(NumGet(1*pdisp)+ 0), "Uint", pdisp, "Uint" , pattr, "UintP", ppv)
DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
If ppv
DllCall(NumGet(NumGet(1*pdisp)+ 8), "Uint", pdisp), pdisp := ppv
}
Return pdisp
}
COM_GetDefaultEvents(pdisp)
{
DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint" , 0, "Uint", 1024, "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
VarSetCapacity(IID,16),DllCall("kernel32\RtlMoveMemory", "Ptr", &IID, "Ptr", pattr, "UPtr", 16)
DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
Loop, % DllCall(NumGet(NumGet(1*ptlib)+12), "Uint", ptlib)
{
DllCall(NumGet(NumGet(1*ptlib)+20), "Uint", ptlib, "Uint", A_Index-1, "UintP", TKind)
If TKind <> 5
Continue
DllCall(NumGet(NumGet(1*ptlib)+16), "Uint", ptlib, "Uint", A_Index-1, "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
nCount:=NumGet(pattr+48,0,"Ushort")
DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
Loop, % nCount
{
DllCall(NumGet(NumGet(1*ptinf)+36), "Uint", ptinf, "Uint", A_Index-1, "UintP", nFlags)
If !(nFlags & 1)
Continue
DllCall(NumGet(NumGet(1*ptinf)+32), "Uint", ptinf, "Uint", A_Index-1, "UintP", hRefType)
DllCall(NumGet(NumGet(1*ptinf)+56), "Uint", ptinf, "Uint", hRefType , "UintP", prinf)
DllCall(NumGet(NumGet(1*prinf)+12), "Uint", prinf, "UintP", pattr)
nFlags & 2 ? DIID:=COM_String4GUID(pattr) : bFind:=COM_IsEqualGUID(pattr,&IID)
DllCall(NumGet(NumGet(1*prinf)+76), "Uint", prinf, "Uint" , pattr)
DllCall(NumGet(NumGet(1*prinf)+ 8), "Uint", prinf)
}
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
If bFind
Break
}
DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
Return bFind ? DIID : "{00000000-0000-0000-0000-000000000000}"
}
COM_GetGuidOfName(pdisp, Name)
{
DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint", 0, "Uint", 1024, "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf), ptinf:=0
DllCall(NumGet(NumGet(1*ptlib)+44), "Uint", ptlib, "Uint", &Name, "Uint", 0, "UintP", ptinf, "UintP", memID, "UshortP", 1)
DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
DllCall(NumGet(NumGet(1*ptinf)+12), "Uint", ptinf, "UintP", pattr)
GUID := COM_String4GUID(pattr)
DllCall(NumGet(NumGet(1*ptinf)+76), "Uint", ptinf, "Uint" , pattr)
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf)
Return GUID
}
COM_GetTypeInfoOfGuid(pdisp, GUID)
{
DllCall(NumGet(NumGet(1*pdisp)+16), "Uint", pdisp, "Uint", 0, "Uint", 1024, "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptinf)+72), "Uint", ptinf, "UintP", ptlib, "UintP", idx)
DllCall(NumGet(NumGet(1*ptinf)+ 8), "Uint", ptinf), ptinf := 0
DllCall(NumGet(NumGet(1*ptlib)+24), "Uint", ptlib, "Uint", COM_GUID4String(GUID,GUID), "UintP", ptinf)
DllCall(NumGet(NumGet(1*ptlib)+ 8), "Uint", ptlib)
Return ptinf
}
COM_ConnectObject(pdisp, prefix = "", DIID = "")
{
pdisp:= COM_Unwrap(pdisp)
If Not DIID
0+(pconn:=COM_FindConnectionPoint(pdisp,"{00020400-0000-0000-C000-000000000046}")) ? (DIID:=COM_GetConnectionInterface(pconn))="{00020400-0000-0000-C000-000000000046}" ? DIID:=COM_GetDefaultEvents(pdisp):"":pconn:=COM_FindConnectionPoint(pdisp,DIID:=COM_GetDefaultEvents(pdisp))
Else pconn:=COM_FindConnectionPoint(pdisp,SubStr(DIID,1,1)="{" ? DIID:DIID:=COM_GetGuidOfName(pdisp,DIID))
If !pconn||!ptinf:=COM_GetTypeInfoOfGuid(pdisp,DIID)
{
MsgBox, No Event Interface Exists!
Return
}
NumPut(pdisp,NumPut(ptinf,NumPut(1,NumPut(COM_CreateIDispatch(),0+psink:=COM_CoTaskMemAlloc(40+nSize:=StrLen(prefix)*2+2)))))
DllCall("kernel32\RtlMoveMemory", "Ptr", psink+24, "Ptr", COM_GUID4String(DIID,DIID), "UPtr", 16)
DllCall("kernel32\RtlMoveMemory", "Ptr", psink+40, "Ptr", &prefix, "UPtr", nSize)
NumPut(COM_Advise(pconn,psink),NumPut(pconn,psink+16))
Return psink
}
COM_DisconnectObject(psink)
{
Return COM_Unadvise(NumGet(psink+16),NumGet(psink+20))=0 ? (0,COM_Release(NumGet(psink+16)),COM_Release(NumGet(psink+8)),COM_CoTaskMemFree(psink)):1
}
COM_CreateObject(CLSID, IID = "", CLSCTX = 21)
{
ppv := COM_CreateInstance(CLSID,IID,CLSCTX)
Return IID=="" ? COM_Enwrap(ppv):ppv
}
COM_GetObject(Name)
{
COM_Init()
If DllCall("ole32\CoGetObject", "Ptr", &Name, "Ptr", 0, "Ptr", COM_GUID4String(IID_IDispatch,"{00020400-0000-0000-C000-000000000046}"), "UIntP", pdisp)=0
Return COM_Enwrap(pdisp)
}
COM_GetActiveObject(CLSID)
{
COM_Init()
If DllCall("oleaut32\GetActiveObject", "Ptr", COM_GUID4String(CLSID,CLSID), "Ptr", 0, "UIntP", punk)=0
&& DllCall(NumGet(NumGet(1*punk)), "Uint", punk, "Uint", COM_GUID4String(IID_IDispatch,"{00020400-0000-0000-C000-000000000046}"), "UintP", pdisp)+DllCall(NumGet(NumGet(1*punk)+8), "Uint", punk)*0=0
Return COM_Enwrap(pdisp)
}
COM_CreateInstance(CLSID, IID = "", CLSCTX = 21)
{
COM_Init()
If DllCall("ole32\CoCreateInstance", "Ptr", COM_GUID4String(CLSID,CLSID), "Ptr", 0, "UInt", CLSCTX, "Ptr", COM_GUID4String(IID,IID ? IID:IID=0 ? "{00000000-0000-0000-C000-000000000046}":"{00020400-0000-0000-C000-000000000046}"), "UIntP", ppv)=0
Return ppv
}
COM_CLSID4ProgID(ByRef CLSID, ProgID)
{
VarSetCapacity(CLSID,16,0)
DllCall("ole32\CLSIDFromProgID", "Ptr", &ProgID, "Ptr", &CLSID)
Return &CLSID
}
COM_ProgID4CLSID(pCLSID)
{
DllCall("ole32\ProgIDFromCLSID", "Ptr", pCLSID, "UIntP", pProgID)
Return StrGet(pProgID) . COM_CoTaskMemFree(pProgID)
}
COM_GUID4String(ByRef CLSID, String)
{
VarSetCapacity(CLSID,16,0)
DllCall("ole32\CLSIDFromString", "Ptr", &String, "Ptr", &CLSID)
Return &CLSID
}
COM_String4GUID(pGUID)
{
VarSetCapacity(String,38*2)
DllCall("ole32\StringFromGUID2", "Ptr", pGUID, "Str", String, "Int", 39)
Return String
}
COM_IsEqualGUID(pGUID1, pGUID2)
{
Return DllCall("ole32\IsEqualGUID", "Ptr", pGUID1, "Ptr", pGUID2)
}
COM_CoCreateGuid()
{
VarSetCapacity(GUID,16,0)
DllCall("ole32\CoCreateGuid", "Ptr", &GUID)
Return COM_String4GUID(&GUID)
}
COM_CoInitialize()
{
Return DllCall("ole32\CoInitialize", "Ptr", 0)
}
COM_CoUninitialize()
{
DllCall("ole32\CoUninitialize")
}
COM_CoTaskMemAlloc(cb)
{
Return DllCall("ole32\CoTaskMemAlloc", "UPtr", cb, "Ptr")
}
COM_CoTaskMemFree(pv)
{
DllCall("ole32\CoTaskMemFree", "Ptr", pv)
}
COM_SysAllocString(str)
{
Return DllCall("oleaut32\SysAllocString", "Ptr", &str, "Ptr")
}
COM_SysFreeString(pstr)
{
DllCall("oleaut32\SysFreeString", "Ptr", pstr)
}
COM_SafeArrayDestroy(psar)
{
Return DllCall("oleaut32\SafeArrayDestroy", "Ptr", psar)
}
COM_VariantClear(pvar)
{
DllCall("oleaut32\VariantClear", "Ptr", pvar)
}
COM_VariantChangeType(pvarDst, pvarSrc, vt = 8)
{
Return DllCall("oleaut32\VariantChangeTypeEx", "Ptr", pvarDst, "Ptr", pvarSrc, "UInt", 1024, "UShort", 0, "UShort", vt)
}
COM_SysString(ByRef wString, sString)
{
VarSetCapacity(wString,4+nLen:=2*StrLen(sString))
Return DllCall("kernel32\lstrcpyW", "Ptr", NumPut(nLen,wString), "Ptr", &sString, "Ptr")
}
COM_AccInit()
{
Static h
If Not h
COM_Init(), h:=DllCall("kernel32\LoadLibrary", "Str", "oleacc", "Ptr")
}
COM_AccTerm()
{
COM_Term()
}
COM_AccessibleChildren(pacc, cChildren, ByRef varChildren)
{
VarSetCapacity(varChildren,cChildren*16,0)
If DllCall("oleacc\AccessibleChildren", "Ptr", COM_Unwrap(pacc), "Int", 0, "Int", cChildren+0, "Ptr", &varChildren, "UIntP", cChildren:=0)=0
Return cChildren
}
COM_AccessibleObjectFromEvent(hWnd, idObject, idChild, ByRef _idChild_="")
{
COM_AccInit(), VarSetCapacity(varChild,16,0)
If DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "UIntP", pacc, "Ptr", &varChild)=0
Return COM_Enwrap(pacc), _idChild_:=NumGet(varChild,8)
}
COM_AccessibleObjectFromPoint(x, y, ByRef _idChild_="")
{
COM_AccInit(), VarSetCapacity(varChild,16,0)
If DllCall("oleacc\AccessibleObjectFromPoint", "UInt64", x&0xFFFFFFFF|y<<32, "UIntP", pacc, "Ptr", &varChild)=0
Return COM_Enwrap(pacc), _idChild_:=NumGet(varChild,8)
}
COM_AccessibleObjectFromWindow(hWnd, idObject=-4, IID = "")
{
COM_AccInit()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", COM_GUID4String(IID, IID ? IID : idObject&0xFFFFFFFF==0xFFFFFFF0 ? "{00020400-0000-0000-C000-000000000046}":"{618736E0-3C3D-11CF-810C-00AA00389B71}"), "UIntP", pacc)=0
Return COM_Enwrap(pacc)
}
COM_WindowFromAccessibleObject(pacc)
{
If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", COM_Unwrap(pacc), "UIntP", hWnd)=0
Return hWnd
}
COM_GetRoleText(nRole)
{
nLen:= DllCall("oleacc\GetRoleTextW", "UInt", nRole, "Ptr", 0, "UInt", 0, "UInt")
VarSetCapacity(sRole,nLen*2)
If DllCall("oleacc\GetRoleTextW", "UInt", nRole, "Str", sRole, "UInt", nLen+1, "UInt")
Return sRole
}
COM_GetStateText(nState)
{
nLen:= DllCall("oleacc\GetStateTextW", "UInt", nState, "Ptr", 0, "UInt", 0, "UInt")
VarSetCapacity(sState,nLen*2)
If DllCall("oleacc\GetStateTextW", "UInt", nState, "Str", sState, "UInt", nLen+1, "UInt")
Return sState
}
COM_AtlAxWinInit(Version = "")
{
Static h
If Not h
COM_Init(), h:=DllCall("kernel32\LoadLibrary", "Str", "atl" . Version, "Ptr"), DllCall("atl" . Version . "\AtlAxWinInit")
}
COM_AtlAxWinTerm(Version = "")
{
COM_Term()
}
COM_AtlAxGetHost(hWnd, Version = "")
{
If DllCall("atl" . Version . "\AtlAxGetHost", "Ptr", hWnd, "UIntP", punk)=0
Return COM_Enwrap(COM_QueryInterface(punk)+COM_Release(punk)*0)
}
COM_AtlAxGetControl(hWnd, Version = "")
{
If DllCall("atl" . Version . "\AtlAxGetControl", "Ptr", hWnd, "UIntP", punk)=0
Return COM_Enwrap(COM_QueryInterface(punk)+COM_Release(punk)*0)
}
COM_AtlAxAttachControl(pdsp, hWnd, Version = "")
{
If DllCall("atl" . Version . "\AtlAxAttachControl", "Ptr", punk:=COM_QueryInterface(pdsp,0), "Ptr", hWnd, "Ptr", COM_AtlAxWinInit(Version))+COM_Release(punk)*0=0
Return COM_Enwrap(pdsp)
}
COM_AtlAxCreateControl(hWnd, Name, Version = "")
{
If DllCall("atl" . Version . "\AtlAxCreateControl", "Ptr", &Name, "Ptr", hWnd, "Ptr", 0, "Ptr", COM_AtlAxWinInit(Version))=0
Return COM_AtlAxGetControl(hWnd,Version)
}
COM_AtlAxCreateContainer(hWnd, l, t, w, h, Name = "", Version = "")
{
Return DllCall("user32\CreateWindowEx", "UInt", 0x200, "Str", "AtlAxWin" . Version, "Ptr", Name?&Name:0, "UInt", 0x54000000, "Int", l, "Int", t, "Int", w, "Int", h, "Ptr", hWnd, "Ptr", 0, "Ptr", 0, "Ptr", COM_AtlAxWinInit(Version), "Ptr")
}
COM_AtlAxGetContainer(pdsp, bCtrl = "")
{
DllCall(NumGet(NumGet(1*pdsp:=COM_Unwrap(pdsp))), "Uint", pdsp, "Uint", COM_GUID4String(IID_IOleWindow,"{00000114-0000-0000-C000-000000000046}"), "UintP", pwin)
DllCall(NumGet(NumGet(1*pwin)+12), "Uint", pwin, "UintP", hCtrl)
DllCall(NumGet(NumGet(1*pwin)+ 8), "Uint", pwin)
Return bCtrl?hCtrl:DllCall("user32\GetParent", "Ptr", hCtrl, "Ptr")
}
COM_ScriptControl(sCode, sEval = "", sName = "", Obj = "", bGlobal = "")
{
oSC:=COM_CreateObject("ScriptControl"), oSC.Language(sEval+0==""?"VBScript":"JScript"), sName&&Obj?oSC.AddObject(sName,Obj,bGlobal):""
Return sEval?oSC.Eval(sEval+0?sCode:sEval oSC.AddCode(sCode)):oSC.ExecuteStatement(sCode)
}
COM_Parameter(typ, prm = "", nam = "")
{
Return IsObject(prm)?prm:Object("typ_",typ,"prm_",prm,"nam_",nam)
}
COM_Enwrap(obj, vt = 9)
{
Static base
Return IsObject(obj)?obj:Object("prm_",obj,"typ_",vt,"base",base?base:base:=Object("__Delete","COM_Invoke","__Call","COM_Invoke","__Get","COM_Invoke","__Set","COM_InvokeSet","base",Object("__Delete","COM_Term")))
}
COM_Unwrap(obj)
{
Return IsObject(obj)?obj.prm_:obj
}