DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

03 May 2017, 16:18

[Update 3:] Latest version:
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
}

;==================================================
E.g. output. This is *NOT* a working x64/x32 compatible version of COM.ahk, however much of the necessary conversion has been done:

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
}
Last edited by jeeswg on 05 Nov 2017, 16:53, edited 10 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

03 May 2017, 18:14

Thank you for this script, but I gotta ask - why would you want to convert COM.ahk to 64-bit?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

03 May 2017, 18:27

I've been working on a project, GUIs via DllCall. The next step is to release a DllCall version of this script:

control zoo (AHK v1.1) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=30652

It is almost finished, however so far the Internet Explorer_Server control requires COM.ahk and only works in x32. I would like to either: make the necessary functions or all of COM.ahk, x64/x32 compatible, or convert the necessary functions to AHK's native COM, or both.

Btw does COM.ahk have any functionality that AHK's native COM doesn't?

This is the script I've based the code for the Internet Explorer_Server control on:

IE_Add() or COM_AtlAxCreateContainer() or AtlAxWin() - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/3213 ... ntry204552

Btw there might be other uses for COM.ahk. It depends on other people.

==================================================

Code I have so far:
- The original GUIs via DllCall code does not use the Gui command, this is a stand-alone version of it.
- I've reduced it to 2 COM.ahk functions, but those COM.ahk functions refer to other functions etc.

Code: Select all

#SingleInstance force
#Include %A_Desktop%\COM.ahk
DetectHiddenWindows, On
Gui, New, +HwndhGui

;==================================================

COM_AtlAxWinInit()
vWinClass := "AtlAxWin", vWinText := "Shell.Explorer"
vWinStyle := 0x54000000, vWinExStyle := 0
vPosX := 0, vPosY := 0, vPosW := 300, vPosH := 300
hWndParent := hGui, hMenu := 0, hInstance := 0, vParam := 0

hCtl := JEE_DCCreateWindowEx(vWinExStyle, vWinClass, vWinText, vWinStyle, vPosX, vPosY, vPosW, vPosH, hWndParent, hMenu, hInstance, vParam)

oWB := COM_AtlAxGetControl(hCtl)
oWB.Navigate("https://www.google.com/")
while oWB.busy || !(oWB.ReadyState = 4)
	Sleep 100
;OLECMDID_OPTICAL_ZOOM := 63 ;OLECMDEXECOPT_DONTPROMPTUSER := 2
oWB.ExecWB(63, 2, 30, 0) ;zoom 30%
oWB.document.parentWindow.scrollBy(120, 35)
Gui, Show, x100 y100 w300 h300
return

;==================================================

JEE_DCCreateWindowEx(vWinExStyle, vWinClass, vWinText, vWinStyle, vPosX, vPosY, vPosW, vPosH, hWndParent, hMenu, hInstance, vParam)
{
	return DllCall("CreateWindowEx", UInt,vWinExStyle, Str,vWinClass, Str,vWinText, UInt,vWinStyle, Int,vPosX, Int,vPosY, Int,vPosW, Int,vPosH, Ptr,hWndParent, Ptr,hMenu, Ptr,hInstance, Ptr,vParam, Ptr)
}

;==================================================
Btw what do you make of the COM.ahk functions, can the ones I've used be easily replaced with native AHK's native COM functions? Do you find the COM.ahk script easy to read or a bit untidy?
Last edited by jeeswg on 04 May 2017, 02:32, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 02:21

OK, re. my IE control script, I've eliminated the need for COM.ahk and made it x64/x32 compatible. So that's the end of that chapter.

They are quite different, the COM.ahk functions and AHK's native COM functions.

Code: Select all

#SingleInstance force
DetectHiddenWindows, On
Gui, New, +HwndhGui

;==================================================

vVersion := ""
DllCall("kernel32\LoadLibrary", Str,"atl" vVersion, Ptr)
DllCall("atl" vVersion "\AtlAxWinInit")

DllCall("ole32\OleInitialize", Ptr,0)
vWinClass := "AtlAxWin", vWinText := "Shell.Explorer"
vWinStyle := 0x54000000, vWinExStyle := 0
vPosX := 0, vPosY := 0, vPosW := 300, vPosH := 300
hWndParent := hGui, hMenu := 0, hInstance := 0, vParam := 0

hCtl := JEE_DCCreateWindowEx(vWinExStyle, vWinClass, vWinText, vWinStyle, vPosX, vPosY, vPosW, vPosH, hWndParent, hMenu, hInstance, vParam)

DllCall("atl" vVersion "\AtlAxGetControl", Ptr,hCtl, UIntP,pUnk)
IID := "{00000000-0000-0000-C000-000000000046}"
;IID := "{00020400-0000-0000-C000-000000000046}" ;this works also
ptr := ComObjQuery(pUnk, IID)
oWB := ComObjEnwrap(ptr), ObjRelease(ptr)
oWB.Navigate("https://www.google.com/")
while oWB.busy || !(oWB.ReadyState = 4)
	Sleep 100
;OLECMDID_OPTICAL_ZOOM := 63 ;OLECMDEXECOPT_DONTPROMPTUSER := 2
oWB.ExecWB(63, 2, 30, 0) ;zoom 30%
oWB.document.parentWindow.scrollBy(120, 35)
Gui, Show, x100 y100 w300 h300
return

;==================================================

JEE_DCCreateWindowEx(vWinExStyle, vWinClass, vWinText, vWinStyle, vPosX, vPosY, vPosW, vPosH, hWndParent, hMenu, hInstance, vParam)
{
	return DllCall("CreateWindowEx", UInt,vWinExStyle, Str,vWinClass, Str,vWinText, UInt,vWinStyle, Int,vPosX, Int,vPosY, Int,vPosW, Int,vPosH, Ptr,hWndParent, Ptr,hMenu, Ptr,hInstance, Ptr,vParam, Ptr)
}

;==================================================
But as per:
ComObjActive()
https://autohotkey.com/docs/commands/ComObjActive.htm

The script seems to crash when trying to convert:
ComObject := ComObjEnwrap(DispPtr)
to the following, or variants of it:
ComObject := ComObject(9, DispPtr, 1), ObjAddRef(DispPtr)

Also, I'm unsure about the differences between the following IIDs:
IID_IUnknown: "{00000000-0000-0000-C000-000000000046}",
IID_IDispatch: "{00020400-0000-0000-C000-000000000046}".

They both worked, and are listed here, but I don't know how they differ:
[MS-OAUT]: Standards Assignments
https://msdn.microsoft.com/en-us/library/cc237842.aspx
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 02:41

Hi jeeswg,

you called this topic "DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)". You shouldn't use this thread as an "Ask For Help" replacement for COM related stuff.

Also, why do you need

Code: Select all

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)
}
There are other functions using a POINT structure, and many DllCalls written for 32-bit are using two parameters in this case.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 03:43

Yes, if the problems were more complex I might have started a new topic.

I didn't know any script writers were splitting up parameters like this until the last few days.

MSDN lists AccessibleObjectFromPoint as a 3-parameter function with an 8-byte POINT parameter, not a 4-parameter function with separate 4-byte x and y parameters. E.g. Acc.ahk uses the POINT structure, COM.ahk uses separate x/y parameters.

My script counts the parameters in a DllCall, and 4 would be the incorrect number. Potentially the script could be made to allow multiple definitions per dll function. Although arguably such a practice should not be encouraged or supported. Anyway, glad you noticed it and glad you brought it up, sharp as ever.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 03:50

Code: Select all

	oTemp := StrSplit(vTemp2, vUnused)
	vCountParam := oTemp.MaxIndex()
creates interesting results if vName isn't "COM.ahk".
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 04:01

Fixed. The assignment of the vUnused variable, which was done under a condition within curly brackets, has now been moved outside.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 04:15

Code: Select all

vText = `r`nDllCall("user32\CreateWindowEx", UInt,vWinExStyle, "Str",vWinClass, "Str",vWinText, "UInt",vWinStyle, "Int",vPosX, "Int",vPosY, "Int",vPosW, "Int",vPosH, "UInt",hWndParent, "UInt",hMenu, "Uint",hInstance, "Uint",vParam, "UInt")`r`n
is converted to

Code: Select all

DllCall("user32\CreateWindowEx", "UInt", vWinExStyle, "Str", vWinClass, "Str", vWinText, "UInt", vWinStyle, "Int", vPosX, "Int", vPosY, "Int", vPosW, "Int", vPosH, "Ptr", hWndParent, "Ptr", hMenu, "Ptr", hInstance, "Ptr", vParam, "Ptr", Ptr)
here.

Also, you should consider
DllFile may be omitted when calling a function that resides in User32.dll, Kernel32.dll, ComCtl32.dll, or Gdi32.dll. For example, "User32\IsWindowVisible" produces the same result as "IsWindowVisible".
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 04:28

Ah, so is that 'DllCall' within a string!? Rather than used as a function? Yes that is uncommon although ultimately the script should be amended to handle that.

The omit the dll name is a bad practice, but it could potentially be supported, I did think of that. I.e. to specify to omit the dll name where possible. Contrariwise, if the dll name is not there, and the user wants it, it should be added, that's a key bit of functionality I meant to add in.

The list of dlls had 'name\function=parameters', but I believe it will work with just 'function=parameters'.

Btw I released the script as it is, because sometimes it's better to provide something now that works in most cases, than to provide nothing and delay by many months.

Do continue to mention any issues, much appreciated.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 04:50

vText is the variable containing the script read from the file. It's not a 'DllCall within a string'.

Related to DLL names you should also consider:

Code: Select all

DllCall("User32.dll\CreateWindowEx", ...
The two-parameter usage for POINT or other 64-bit structures is valid for AHK 32-bit. It's exactly what is passed on the stack: two 32-bit values.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 04:55

So what's the problem with vText? That it ate the enters? Which is obviously a problem. Otherwise it looks fine.

Btw are you saying that the 8-byte to 2 4-byte parameter split only works on AHK x32 and not AHK x64?

Re. CreateWindowEx are you saying to consider the '.dll'. I agree, that and W/A. Plus parameters that vary based on whether the script is Unicode/Ansi. And also if variables are used for parameter types to handle that.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

04 May 2017, 05:17

The problem is: ... "Ptr", hMenu, "Ptr", hInstance, "Ptr", vParam, "Ptr", Ptr)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

28 Sep 2017, 16:07

Introducing the new function.

There are 6 key options re. DllCall, summarised as: CGKU/.dll/Int/*/", pairing: remove comctl32/gdi32/kernel32/user32, remove .dll, remove Int when it's the return type, use * or P, remove double quotes from parameter types (where possible), group 'type, argument' pairs (remove the space in-between).

Code: Select all

;My preference is as follows:
DllCall("kernel32\MyFunc", PtrP,MyArg)
DllCall("MyDll\MyFunc", PtrP,MyArg)

;The opposite 6 choices would be:
DllCall("MyFunc", "Ptr*", MyArg, "Int")
DllCall("MyDll.dll\MyFunc", "Ptr*", MyArg, "Int")
The function can be set simply to tidy what it sees, 'z' mode, but it can also actively try to correct information (alter parameter types and add in dll names) based on a list of dll functions and their parameter types.

The script hasn't been designed to handle parameters that are continuation sections, so I'm not sure what would happen if you tried to do this.

The function removes leading whitespace, comments and continuation sections, performs the changes, then restores the whitespace/comments/continuation sections.

==================================================

@just me: The function is fixed now, it was a quite a simple fix, see lines containing 'EDIT'.

Re. POINT structures, in this more recent discussion it has emerged that it would probably be better to not allow splitting a parameter:

script does not work in 64 bit AHK - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 36#p167136

My function does not include support for it. Besides, it only relates to relatively few functions: WindowFromPoint, AccessibleObjectFromPoint. Furthermore, handling the X and Y values can be made easier by using a MakeUInt64 function, see:

Wish List 2.0 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 60#p171860
Last edited by jeeswg on 28 Sep 2017, 16:44, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

28 Sep 2017, 16:09

I have done a lot work to the original function, I now have JEE_TidyDllCall, and related functions: JEE_FuncPrepare and JEE_DllParamListExpand. I also include JEE_CmdPrepare which isn't really related to correcting DllCall lines.

Code: Select all

;==================================================
;e.g.
;FileRead, vText, % A_ScriptFullPath
;vOutput := JEE_TidyDllCall(vText, "np", oListUndefined)
;MsgBox, % oListUndefined.Length()
;JEE_WinMergeCompareStrings(vText, vOutput)
;return

;JEE_TidyDllCall requires JEE_FuncPrepare and JEE_DllParamListExpand

;styles: dll name:
;DllCall("Func", T1,A1, T2,A2, RT) ;omit when possible (comctl32/gdi32/kernel32/user32)
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;always show ;DEFAULT

;styles: dll name (extension):
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;DEFAULT
;DllCall("Dll.dll\Func", T1,A1, T2,A2, RT)

;styles: return parameter:
;DllCall("Dll\Func", T1,A1, T2,A2) ;omit when possible (Int) ;DEFAULT
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;always show

;styles: parameters: spacing:
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;DEFAULT
;DllCall("Dll\Func", T1, A1, T2, A2, RT)

;styles: parameters: double quotes:
;Int ;DEFAULT
;"Int"

;styles: parameters:
;IntP or "IntP" ;DEFAULT
;"Int*"

;vOpt:
;n: always include dll name (else omit comctl32/gdi32/kernel32/user32)
;x: always include .dll e.g. 'DllName.dll\Func' (else 'DllName\Func')
;r: always include return type (else omit Int)
;p: use pair style e.g. 'T1,A1, T2,A2' (else 'T1, A1, T2, A2')
;q: use quotes style e.g. "Int" (else Int)
;s: use star style e.g. Int* (else IntP)

;z: adjust style, not content: do not try to edit the function name, or change/remove parameter types (tidy parameter types, and parameter grouping)
;d1/d2/d3: diagnostic modes (show MsgBox)

JEE_TidyDllCall(vText, vOpt:="np", ByRef oListUndefined:="")
{
	static vIsV1 := !!SubStr(1,0)
	static vDQ := Chr(34)
	static vBarrier := "=================================================="
	static vIsInit := 0, oDllInfo := {}, oDllName := {}
	static vList := "Ptr,Int64,Int,Short,Char,Float,Double"
	static vListU := "UPtr,UInt64,UInt,UShort,UChar"
	static vListC := "CDecl Ptr,CDecl Int64,CDecl Int,CDecl Short,CDecl Char,CDecl Float,CDecl Double"
	static vListCU := "CDecl UPtr,CDecl UInt64,CDecl UInt,CDecl UShort,CDecl UChar"
	static vListP := "PtrP,Int64P,IntP,ShortP,CharP,FloatP,DoubleP"
	static vListPU := "UPtrP,UInt64P,UIntP,UShortP,UCharP"
	static vListA := "Ptr*,Int64*,Int*,Short*,Char*,Float*,Double*"
	static vListAU := "UPtr*,UInt64*,UInt*,UShort*,UChar*"
	static vListS := "Str,AStr,WStr"
	static vListPtr := vListP "," vListPU "," vListA "," vListAP "," vListS
	static vListAll := vList "," vListU "," vListPtr
	static vListPtr2 := "i)^(" StrReplace(StrReplace(vListPtr, ",", "|"), "*", "\*") ")$"
	local oArrayL,oArrayT,oList
	local oTemp,vAddDllExt,vAddDllNameCGKU,vAddRetTypeInt,vArgPfx,vArgSfx,vCount,vCountFull,vCountParam,vDoChangeStyleOnly,vDoMsgBeforeAfter,vDoMsgUnknownFunc,vDoMsgUnknownType,vDoPairStyle,vDoQuotesStyle,vDoStarStyle,vErrorNoEnd,vHasUnknownType,vIndex,vIndexParam,vIsConSec,vIsMatch,vLen,vListDllFunc,vListType,vNoName,vOutput,vParam,vParamOrig,vPos,vPosOrig,vPrompt,vSfx,vTemp,vTemp2,vTempOrig,vTempX,vTypePfx,vTypeSfx,vUnused,vWithExt

	vAddDllNameCGKU := !!InStr(vOpt, "n")
	vAddDllExt := !!InStr(vOpt, "x")
	vAddRetTypeInt := !!InStr(vOpt, "r")
	vDoPairStyle := !!InStr(vOpt, "p")
	vDoQuotesStyle := !!InStr(vOpt, "q")
	vDoStarStyle := !!InStr(vOpt, "s")
	vDoChangeStyleOnly := !!InStr(vOpt, "z")
	;vTypePfx := " ", vTypeSfx := ""
	vArgPfx := vDoPairStyle?"":" ",	vArgSfx := ""

	vDoMsgBeforeAfter := !!InStr(vOpt, "d1") ;diagnostic
	vDoMsgUnknownFunc := !!InStr(vOpt, "d2") ;diagnostic
	vDoMsgUnknownType := !!InStr(vOpt, "d3") ;diagnostic

	;==============================

	vListDllFunc = ;continuation section
	(LTrim
	advapi32\AdjustTokenPrivileges=tituitt(i)
	advapi32\CryptAcquireContextW=tttuiui(i)
	advapi32\CryptCreateHash=utuiutuit(i)
	advapi32\CryptDestroyHash=ut(i)
	advapi32\CryptGetHashParam=utuittui(i)
	advapi32\CryptHashData=uttuiui(i)
	advapi32\CryptReleaseContext=utui(i)
	advapi32\IsTextUnicode=tit(i)
	advapi32\LookupPrivilegeValueW=ttt(i)
	advapi32\OpenProcessToken=tuit(i)
	advapi32\RegOpenKeyExW=ttuiuit(i)
	advapi32\RegQueryInfoKeyW=tttttttttttt(i)
	advapi32\RegQueryValueExW=tttttt(i)
	atl\AtlAxAttachControl=ttt(i)
	atl\AtlAxCreateControl=tttt(i)
	atl\AtlAxGetControl=tt(i)
	atl\AtlAxGetHost=tt(i)
	atl\AtlAxWinInit=(i)
	comctl32\ImageList_Add=ttt(i)
	comctl32\ImageList_Create=iiuiii(t)
	comctl32\ImageList_Replace=titt(i)
	comctl32\ImageList_ReplaceIcon=tit(i)
	comctl32\InitCommonControlsEx=t(i)
	comdlg32\GetFileTitle=ttuh(h)
	crypt32\CryptBinaryToString=tuiuitt(i)
	crypt32\CryptStringToBinaryW=tuiuitttt(i)
	dwmapi\DwmGetWindowAttribute=tuitui(i)
	dwmapi\DwmIsCompositionEnabled=t(i)
	gdi32\BitBlt=tiiiitiiui(i)
	gdi32\CreateCompatibleBitmap=tii(t)
	gdi32\CreateCompatibleDC=t(t)
	gdi32\CreateDIBSection=ttuittui(t)
	gdi32\CreateFontIndirectA=t(t)
	gdi32\CreateFontIndirectW=t(t)
	gdi32\CreateFontW=iiiiiuiuiuiuiuiuiuiuit(t)
	gdi32\CreatePen=iiui(t)
	gdi32\CreateSolidBrush=ui(t)
	gdi32\DeleteDC=t(i)
	gdi32\DeleteEnhMetaFile=t(i)
	gdi32\DeleteObject=t(i)
	gdi32\GetDeviceCaps=ti(i)
	gdi32\GetDIBits=ttuiuittui(i)
	gdi32\GetEnhMetaFileBits=tuit(ui)
	gdi32\GetFontUnicodeRanges=tt(ui)
	gdi32\GetObjectType=t(ui)
	gdi32\GetObjectW=tit(i)
	gdi32\GetStockObject=i(t)
	gdi32\GetTextExtentPoint32W=ttit(i)
	gdi32\GetTextFaceW=tit(i)
	gdi32\RealizePalette=t(ui)
	gdi32\Rectangle=tiiii(i)
	gdi32\SelectObject=tt(t)
	gdi32\SelectPalette=tti(t)
	gdi32\SetBkColor=tui(ui)
	gdi32\SetEnhMetaFileBits=uit(t)
	gdi32\SetStretchBltMode=ti(i)
	gdi32\SetTextColor=tui(ui)
	gdi32\StretchBlt=tiiiitiiiiui(i)
	gdiplus\GdipBitmapGetPixel=tiit(i)
	gdiplus\GdipCreateBitmapFromHBITMAP=ttt(i)
	gdiplus\GdipCreateBitmapFromStream=tt(i)
	gdiplus\GdipCreateHBITMAPFromBitmap=ttui(i)
	gdiplus\GdipDisposeImage=t(i)
	gdiplus\GdipGetImageHeight=tt(i)
	gdiplus\GdipGetImageWidth=tt(i)
	gdiplus\GdiplusShutdown=ut(i)
	gdiplus\GdiplusStartup=uttt(i)
	imagehlp\ImageDirectoryEntryToData=tucuht(t)
	imagehlp\ImageRvaToVa=ttuit(t)
	imagehlp\MapAndLoad=tttii(i)
	imagehlp\UnMapAndLoad=t(i)
	kernel32\AllocConsole=(i)
	kernel32\AttachConsole=ui(i)
	kernel32\CloseHandle=t(i)
	kernel32\CreateFileW=tuiuituiuit(t)
	kernel32\CreateProcessW=ttttiuitttt(i)
	kernel32\CreateRemoteThread=ttutttuit(t)
	kernel32\CreateToolhelp32Snapshot=uiui(t)
	kernel32\DeleteFileA=t(i)
	kernel32\DeleteFileW=t(i)
	kernel32\DeviceIoControl=tuituituitt(i)
	kernel32\ExpandEnvironmentStringsW=ttui(ui)
	kernel32\FileTimeToLocalFileTime=tt(i)
	kernel32\FileTimeToSystemTime=tt(i)
	kernel32\FindClose=t(i)
	kernel32\FindFirstFileW=tt(t)
	kernel32\FindNextFileW=tt(i)
	kernel32\FindResourceW=ttt(t)
	kernel32\FormatMessage=uituiuituit(ui)
	kernel32\FormatMessageA=uituiuituit(ui)
	kernel32\FormatMessageW=uituiuituit(ui)
	kernel32\FreeConsole=(i)
	kernel32\FreeLibrary=t(i)
	kernel32\GetACP=(ui)
	kernel32\GetCommandLineW=(t)
	kernel32\GetCurrentProcessId=(ui)
	kernel32\GetCurrentThreadId=(ui)
	kernel32\GetDiskFreeSpaceExW=tttt(i)
	kernel32\GetEnvironmentVariableW=ttui(ui)
	kernel32\GetExitCodeThread=tt(i)
	kernel32\GetFileAttributesW=t(ui)
	kernel32\GetFileSizeEx=tt(i)
	kernel32\GetFullPathNameW=tuitt(ui)
	kernel32\GetLastError=(ui)
	kernel32\GetLocalTime=t(i)
	kernel32\GetLogicalDrives=(ui)
	kernel32\GetLogicalDriveStringsW=uit(ui)
	kernel32\GetLongPathNameW=ttui(ui)
	kernel32\GetModuleFileNameW=ttui(ui)
	kernel32\GetModuleHandleW=t(t)
	kernel32\GetPriorityClass=t(ui)
	kernel32\GetProcAddress=tt(t)
	kernel32\GetProcessTimes=ttttt(i)
	kernel32\GetShortPathNameW=ttui(ui)
	kernel32\GetStdHandle=ui(t)
	kernel32\GetSystemTime=t(i)
	kernel32\GetSystemTimeAsFileTime=t(i)
	kernel32\GetTempFileNameW=ttuit(ui)
	kernel32\GetTimeZoneInformationForYear=uhtt(i)
	kernel32\GetVersion=(ui)
	kernel32\GetVersionExW=t(i)
	kernel32\GlobalAlloc=uiut(t)
	kernel32\GlobalFree=t(t)
	kernel32\GlobalLock=t(t)
	kernel32\GlobalSize=t(ut)
	kernel32\GlobalUnlock=t(i)
	kernel32\IsWow64Process=tt(i)
	kernel32\LCMapStringW=uiuititi(i)
	kernel32\LoadLibrary=t(t)
	kernel32\LoadLibraryW=t(t)
	kernel32\LoadResource=tt(t)
	kernel32\LocalFileTimeToFileTime=tt(i)
	kernel32\LockResource=t(t)
	kernel32\lstrcpy=tt(t)
	kernel32\lstrcpyn=tti(t)
	kernel32\lstrcpyW=tt(t)
	kernel32\lstrlen=t(i)
	kernel32\Module32First=tt(i)
	kernel32\Module32FirstW=tt(i)
	kernel32\Module32Next=tt(i)
	kernel32\Module32NextW=tt(i)
	kernel32\MulDiv=iii(i)
	kernel32\MultiByteToWideChar=uiuititi(i)
	kernel32\OpenProcess=uiiui(t)
	kernel32\QueryPerformanceCounter=t(i)
	kernel32\ReadFile=ttuitt(i)
	kernel32\ReadProcessMemory=tttutt(i)
	kernel32\RtlMoveMemory=ttut(i)
	kernel32\SetFilePointerEx=ti6tui(i)
	kernel32\SetFileTime=tttt(i)
	kernel32\SetLastError=ui(i)
	kernel32\SetPriorityClass=tui(i)
	kernel32\SetProcessShutdownParameters=uiui(i)
	kernel32\SetSystemTime=t(i)
	kernel32\SizeofResource=tt(ui)
	kernel32\Sleep=ui(i)
	kernel32\SystemTimeToFileTime=tt(i)
	kernel32\SystemTimeToTzSpecificLocalTime=ttt(i)
	kernel32\TzSpecificLocalTimeToSystemTime=ttt(i)
	kernel32\VirtualAllocEx=ttutuiui(t)
	kernel32\VirtualFreeEx=ttutui(i)
	kernel32\VirtualProtect=tutuit(i)
	kernel32\VirtualProtectEx=ttutuit(i)
	kernel32\VirtualQueryEx=tttut(ut)
	kernel32\WaitForSingleObject=tui(ui)
	kernel32\WideCharToMultiByte=uiuitititt(i)
	kernel32\Wow64DisableWow64FsRedirection=t(i)
	kernel32\WriteFile=ttuitt(i)
	kernel32\WriteProcessMemory=tttutt(i)
	magnification\MagInitialize=(i)
	magnification\MagSetWindowTransform=tt(i)
	magnification\MagUninitialize=(i)
	msvcrt\atan2=dd(ed)
	msvcrt\atof=t(ed)
	msvcrt\memcmp=ttut(ei)
	msvcrt\memcpy=ttut(ei)
	ntdll\RtlComputeCrc32=uiti(ui)
	ntdll\RtlFillMemory=tutuc(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\CoInitializeEx=tui(i)
	ole32\CoTaskMemAlloc=ut(t)
	ole32\CoTaskMemFree=t(i)
	ole32\CoUninitialize=(i)
	ole32\CreateStreamOnHGlobal=tit(i)
	ole32\IsEqualGUID=tt(i)
	ole32\OleInitialize=t(i)
	ole32\OleUninitialize=(i)
	ole32\ProgIDFromCLSID=tt(i)
	ole32\StringFromCLSID=tt(i)
	ole32\StringFromGUID2=tti(i)
	oleacc\AccessibleChildren=tiitt(i)
	oleacc\AccessibleObjectFromEvent=tuiuitt(i)
	oleacc\AccessibleObjectFromPoint=ui6tt(i)
	oleacc\AccessibleObjectFromWindow=tuitt(i)
	oleacc\GetRoleTextA=uitui(ui)
	oleacc\GetRoleTextW=uitui(ui)
	oleacc\GetStateTextA=uitui(ui)
	oleacc\GetStateTextW=uitui(ui)
	oleacc\ObjectFromLresult=ttutt(i)
	oleacc\WindowFromAccessibleObject=tt(i)
	oleaut32\DispGetParam=tuiuhtt(i)
	oleaut32\GetActiveObject=ttt(i)
	oleaut32\SafeArrayAccessData=tt(i)
	oleaut32\SafeArrayDestroy=t(i)
	oleaut32\SafeArrayGetDim=t(ui)
	oleaut32\SafeArrayPtrOfIndex=ttt(i)
	oleaut32\SafeArrayUnaccessData=t(i)
	oleaut32\SysAllocString=t(t)
	oleaut32\SysFreeString=t(i)
	oleaut32\SysStringLen=t(ui)
	oleaut32\VariantChangeTypeEx=ttuiuhuh(i)
	oleaut32\VariantClear=t(i)
	powrprof\SetSuspendState=ucucuc(uc)
	propsys\PSGetNameFromPropertyKey=tt(i)
	propsys\PSGetPropertyKeyFromName=tt(i)
	psapi\EnumProcesses=tuit(i)
	psapi\GetMappedFileNameW=tttui(ui)
	psapi\GetModuleBaseNameW=tttui(ui)
	psapi\GetModuleFileNameExA=tttui(ui)
	psapi\GetModuleFileNameExW=tttui(ui)
	psapi\GetProcessImageFileNameW=ttui(ui)
	shell32\DllGetVersion=t(i)
	shell32\DragFinish=t(i)
	shell32\DragQueryFile=tuitui(ui)
	shell32\ExtractIconEx=tittui(ui)
	shell32\ILFree=t(i)
	shell32\ILGetSize=t(ui)
	shell32\SHAddToRecentDocs=uit(i)
	shell32\SHBindToParent=tttt(i)
	shell32\SHChangeNotify=iuitt(i)
	shell32\Shell_NotifyIcon=uit(i)
	shell32\SHGetFileInfo=tuituiui(ut)
	shell32\SHGetFileInfoW=tuituiui(ut)
	shell32\SHGetFolderLocation=tituit(i)
	shell32\SHGetFolderPathW=tituit(i)
	shell32\SHOpenFolderAndSelectItems=tuitui(i)
	shell32\SHParseDisplayName=tttuit(i)
	shell32\SHQueryRecycleBinA=tt(i)
	shlwapi\AssocQueryStringW=uittttt(i)
	shlwapi\PathCreateFromUrlW=tttui(i)
	shlwapi\SHGetViewStatePropertyBag=ttuitt(i)
	shlwapi\StrCmpLogicalW=tt(i)
	shlwapi\StrCmpNW=tti(i)
	shlwapi\StrStrIW=tt(t)
	shlwapi\UrlCreateFromPathW=tttui(i)
	user32\AppendMenuA=tuiutt(i)
	user32\AppendMenuW=tuiutt(i)
	user32\AttachThreadInput=uiuii(i)
	user32\CallNextHookEx=tiutt(t)
	user32\CallWindowProcA=ttuiutt(t)
	user32\CallWindowProcW=ttuiutt(t)
	user32\CharLowerW=t(t)
	user32\CharUpperW=t(t)
	user32\CheckMenuItem=tuiui(ui)
	user32\ClientToScreen=tt(i)
	user32\CloseClipboard=(i)
	user32\CopyIcon=t(t)
	user32\CopyImage=tuiiiui(t)
	user32\CountClipboardFormats=(i)
	user32\CreateCaret=ttii(i)
	user32\CreateCursor=tiiiitt(t)
	user32\CreateDialogParamW=ttttt(t)
	user32\CreateIconFromResourceEx=tuiiuiiiui(t)
	user32\CreateMenu=(t)
	user32\CreatePopupMenu=(t)
	user32\CreateWindowEx=uittuiiiiitttt(t)
	user32\CreateWindowExW=uittuiiiiitttt(t)
	user32\DefWindowProcW=tuiutt(t)
	user32\DestroyIcon=t(i)
	user32\DestroyMenu=t(i)
	user32\DrawIconEx=tiitiiuitui(i)
	user32\DrawTextExW=ttituit(i)
	user32\DrawTextW=ttitui(i)
	user32\EmptyClipboard=(i)
	user32\EnableMenuItem=tuiui(i)
	user32\EnumClipboardFormats=ui(ui)
	user32\EnumDisplayDevicesW=tuitui(i)
	user32\EnumPropsExA=ttt(i)
	user32\EnumPropsExW=ttt(i)
	user32\EnumWindows=tt(i)
	user32\FillRect=ttt(i)
	user32\FindWindowExW=tttt(t)
	user32\FindWindowW=tt(t)
	user32\GetActiveWindow=(t)
	user32\GetAncestor=tui(t)
	user32\GetCaretBlinkTime=(ui)
	user32\GetCaretPos=t(i)
	user32\GetClassLongW=ti(ui)
	user32\GetClientRect=tt(i)
	user32\GetClipboardData=ui(t)
	user32\GetClipboardFormatNameW=uiti(i)
	user32\GetCursorInfo=t(i)
	user32\GetCursorPos=t(i)
	user32\GetDC=t(t)
	user32\GetDCEx=ttui(t)
	user32\GetDlgCtrlID=t(i)
	user32\GetFocus=(t)
	user32\GetForegroundWindow=(t)
	user32\GetGUIThreadInfo=uit(i)
	user32\GetIconInfo=tt(i)
	user32\GetKeyNameTextW=iti(i)
	user32\GetLastActivePopup=t(t)
	user32\GetMenu=t(t)
	user32\GetMenuBarInfo=tiit(i)
	user32\GetMenuItemCount=t(i)
	user32\GetMenuItemID=ti(ui)
	user32\GetMenuItemInfoW=tuiit(i)
	user32\GetMenuItemRect=ttuit(i)
	user32\GetMenuState=tuiui(ui)
	user32\GetMenuStringW=tuitiui(i)
	user32\GetOpenClipboardWindow=(t)
	user32\GetParent=t(t)
	user32\GetPropA=tt(t)
	user32\GetPropW=tt(t)
	user32\GetScrollPos=ti(i)
	user32\GetShellWindow=(t)
	user32\GetSubMenu=ti(t)
	user32\GetSysColor=i(ui)
	user32\GetSystemMenu=ti(t)
	user32\GetWindow=tui(t)
	user32\GetWindowInfo=tt(i)
	user32\GetWindowLongW=ti(i)
	user32\GetWindowRect=tt(i)
	user32\GetWindowRgnBox=tt(i)
	user32\GetWindowTextA=tti(i)
	user32\GetWindowThreadProcessId=tt(ui)
	user32\HideCaret=t(i)
	user32\InsertMenuW=tuiuiutt(i)
	user32\IntersectRect=ttt(i)
	user32\InvalidateRect=tti(i)
	user32\IsCharAlphaW=uh(i)
	user32\IsChild=tt(i)
	user32\IsClipboardFormatAvailable=ui(i)
	user32\IsRectEmpty\t(i)
	user32\IsWindow=t(i)
	user32\IsWindowUnicode=t(i)
	user32\IsWindowVisible=t(i)
	user32\LoadCursorFromFileW=t(t)
	user32\LoadCursorW=tt(t)
	user32\LoadIconW=tt(t)
	user32\LoadImageA=ttuiiiui(t)
	user32\LoadImageW=ttuiiiui(t)
	user32\LoadStringW=tuiti(i)
	user32\LockWorkStation=(i)
	user32\MapWindowPoints=tttui(i)
	user32\MessageBoxW=tttui(i)
	user32\ModifyMenuW=tuiuiutt(i)
	user32\OpenClipboard=t(i)
	user32\PaintDesktop=t(i)
	user32\PostMessageW=tuiutt(i)
	user32\PrintWindow=ttui(i)
	user32\PrivateExtractIconsW=tiiittuiui(ui)
	user32\RedrawWindow=tttui(i)
	user32\RegisterClassExA=t(uh)
	user32\RegisterClassExW=t(uh)
	user32\RegisterClassW=t(uh)
	user32\RegisterClipboardFormatW=t(ui)
	user32\RegisterWindowMessageW=t(ui)
	user32\ReleaseDC=tt(i)
	user32\RemoveMenu=tuiui(i)
	user32\ScreenToClient=tt(i)
	user32\SendMessageA=tuiutt(t)
	user32\SendMessageW=tuiutt(t)
	user32\SetCaretBlinkTime=ui(i)
	user32\SetClassLongW=tii(ui)
	user32\SetClipboardData=uit(t)
	user32\SetCursorPos=ii(i)
	user32\SetForegroundWindow=t(i)
	user32\SetMenu=tt(i)
	user32\SetMenuInfo=tt(i)
	user32\SetMenuItemBitmaps=tuiuitt(i)
	user32\SetMenuItemInfoW=tuiit(i)
	user32\SetParent=tt(t)
	user32\SetRect=tiiii(i)
	user32\SetSysColors=itt(i)
	user32\SetSystemCursor=tui(i)
	user32\SetWindowLongW=tii(i)
	user32\SetWindowPos=ttiiiiui(i)
	user32\SetWindowsHookExW=ittui(t)
	user32\SetWinEventHook=uiuittuiuiui(t)
	user32\ShowCaret=t(i)
	user32\ShowWindow=ti(i)
	user32\SystemParametersInfoA=uiuitui(i)
	user32\SystemParametersInfoW=uiuitui(i)
	user32\TrackPopupMenu=tuiiiitt(i)
	user32\TrackPopupMenuEx=tuiiitt(i)
	user32\UnhookWinEvent=t(i)
	user32\UpdateLayeredWindow=ttttttuitui(i)
	uxtheme\SetWindowThemeAttribute=tttui(i)
	version\GetFileVersionInfoA=tuiuit(i)
	version\GetFileVersionInfoSizeA=tt(ui)
	version\GetFileVersionInfoSizeW=tt(ui)
	version\GetFileVersionInfoW=tuiuit(i)
	version\VerQueryValueA=tttt(i)
	version\VerQueryValueW=tttt(i)
	wininet\FtpCreateDirectoryW=tt(i)
	wininet\FtpDeleteFileW=tt(i)
	wininet\FtpFindFirstFileW=tttuiut(t)
	wininet\FtpGetCurrentDirectoryW=ttt(i)
	wininet\FtpGetFileSize=tt(ui)
	wininet\FtpGetFileW=tttiuiuiut(i)
	wininet\FtpOpenFileW=ttuiuiut(t)
	wininet\FtpPutFileW=tttuiut(i)
	wininet\FtpRemoveDirectoryW=tt(i)
	wininet\FtpRenameFileW=ttt(i)
	wininet\FtpSetCurrentDirectoryW=tt(i)
	wininet\InternetCloseHandle=t(i)
	wininet\InternetConnectW=ttuhttuiuiut(t)
	wininet\InternetFindNextFileW=tt(i)
	wininet\InternetGetLastResponseInfoW=ttt(i)
	wininet\InternetOpenUrlW=tttuiuiut(t)
	wininet\InternetOpenW=tuittui(t)
	wininet\InternetQueryDataAvailable=ttuiut(i)
	wininet\InternetReadFile=ttuit(i)
	wininet\InternetSetStatusCallback=tt(t)
	wininet\InternetWriteFile=ttuit(i)
	winmm\timeBeginPeriod=ui(ui)
	winmm\timeEndPeriod=ui(ui)
	ws2_32\htons=uh(uh)
	ws2_32\WSACleanup=(i)
	ws2_32\WSAStartup=uht(i)
	)

	;==============================

	;STAGE - prepare list of dll functions + parameters
	if !vIsInit
	{
		vIsInit := 1
		Loop, Parse, vListDllFunc, `n
		{
			oTemp := StrSplit(A_LoopField, "=")
			if !(oTemp.Length() = 2)
				continue
			vWithExt := StrReplace(oTemp.1, "\", ".dll\")
			vNoName := RegExReplace(oTemp.1, "^.*\\")
			oDllName[oTemp.1] := oTemp.1
			oDllName[vWithExt] := vWithExt
			oDllName[vNoName] := vNoName
			oDllInfo[oTemp.1] := oTemp.2 ;Dll\Func
			oDllInfo[vWithExt] := oTemp.2 ;Dll.dll\Func
			oDllInfo[vNoName] := oTemp.2 ;Func
			if RegExMatch(oTemp.1, "(A|W)$")
			{
				oDllInfo[SubStr(oTemp.1, 1, -1)] := oTemp.2
				oDllInfo[SubStr(vWithExt, 1, -1)] := oTemp.2
				oDllInfo[SubStr(vNoName, 1, -1)] := oTemp.2
				oDllName[SubStr(oTemp.1, 1, -1)] := SubStr(oTemp.1, 1, -1)
				oDllName[SubStr(vWithExt, 1, -1)] := SubStr(vWithExt, 1, -1)
				oDllName[SubStr(vNoName, 1, -1)] := SubStr(vNoName, 1, -1)
			}
		}
		oDllInfo[""] := ""
	}

	;==============================

	;STAGE - remove leading whitespace, comments, continuation sections
	StrReplace(vText, "`n", "", vCount)
	(oArrayL := {}).SetCapacity(vCount+1)
	(oArrayT := {}).SetCapacity(vCount+1)
	oListUndefined := {}
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, Parse, vText, `n, `r
	{
		vTemp := A_LoopField
		if (vPos := RegExMatch(vTemp, "^;|[ `t];"))
		{
			oArrayT[A_Index] := SubStr(vTemp, vPos)
			vTemp := SubStr(vTemp, 1, vPos-1)
		}
		if (SubStr(vTemp, 1, 1) = ")")
			vIsConSec := 0
		if vIsConSec
		{
			oArrayL[A_Index] := vTemp
			vOutput .= "`n"
			continue
		}
		if (vPos := RegExMatch(vTemp, "[ `t]*\K"))
		{
			oArrayL[A_Index] := SubStr(vTemp, 1, vPos-1)
			vTemp := SubStr(vTemp, vPos)
		}
		if !vIsConSec && (SubStr(vTemp, 1, 1) = "(") && !InStr(vTemp, ")")
			vIsConSec := 1
		vOutput .= vTemp "`n"
	}
	vText := SubStr(vOutput, 1, -1)

	;vUnused := JEE_StrUnused(vText)
	vUnused := Chr(1)
	if InStr(vText, vUnused)
	{
		MsgBox, % "error: no available unused character found"
		return
	}

	;==============================

	;STAGE - find each occurrence of DllCall and convert it
	vPosOrig := 0
	Loop
	{
		vPos := InStr(vText, "DllCall(", 0, vPosOrig+1)
		if !vPos
			break
		vPosOrig := vPos
		if (vPos > 1) && RegExMatch(SubStr(vText, vPos-1, 1), "[\w\x22]")
			continue
		;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
		vTemp2 := JEE_FuncPrepare(vText, vPos, vUnused, vErrorNoEnd)
		if vErrorNoEnd
		{
			MsgBox, % "warning: no end of DllCall line found"
			continue
		}
		vTemp := StrReplace(vTemp2, vUnused, ",")
		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)

		;ignore certain dll name strings
		if (SubStr(vTempX, 1, 7) = "NumGet(")
			continue
		vTempX := StrReplace(vTempX, "(A_IsUnicode?" vDQ "W" vDQ ":" vDQ "A" vDQ) ;(A_IsUnicode?"W":"A" vDQ)
		vTempX := StrReplace(vTempX, " vSfx")
		vTempX := Trim(vTempX)
		if (SubStr(vTempX, 1, 1) = Chr(34)) && (SubStr(vTempX, vIsV1-1) = Chr(34))
			vTempX := SubStr(vTempX, 2, -1)
		vListType := oDllInfo[vTempX]
		if !vDoChangeStyleOnly
		{
			if (vTempX = oDllName[vTempX])
				oTemp.1 := StrReplace(oTemp.1, vTempX, oDllName[vTempX])
		}
		oList := JEE_DllParamListExpand(vListType)
		vCountFull := oList.Length()*2
		if !vDoChangeStyleOnly
		{
			if (vCountParam = vCountFull-1)
			&& (!(oList[oList.MaxIndex()] = "Int") || vAddRetTypeInt)
				oTemp[oTemp.MaxIndex()+1] := oList[oList.MaxIndex()]
			if (vCountParam = vCountFull)
			&& (oList[oList.MaxIndex()] = "Int") && !vAddRetTypeInt
				oTemp.Pop()
		}

		;==================================================

		;STAGE - convert parameter types
		vHasUnknownType := 0
		vIndexParam := 1
		Loop, % oTemp.MaxIndex()
		{
			vTemp := Trim(oTemp[A_Index])
			if (A_Index = 1)
			{
				if !vDoChangeStyleOnly && vAddDllNameCGKU
				{
					vTemp := Trim(SubStr(oTemp.1, 9), Chr(34))
					if !InStr(vTemp, "\") && !InStr(vTemp, " ")
						Loop, Parse, % "comctl|gdi|kernel|user", |
							if oDllName.HasKey(A_LoopField "32\" vTemp)
								oTemp.1 := "DllCall(" Chr(34) A_LoopField "32\" vTemp Chr(34)
				}
				else if !vDoChangeStyleOnly
					oTemp.1 := RegExReplace(oTemp[1], "i)\x22\K(comctl|gdi|kernel|user)32(.dll)?\\")
				if !vDoChangeStyleOnly && vAddDllExt
				{
					if InStr(oTemp.1, "\") && !InStr(oTemp.1, ".dll\")
						oTemp.1 := StrReplace(oTemp.1, "\", ".dll\")
				}
				else if !vDoChangeStyleOnly
				{
					if InStr(oTemp.1, "\") && InStr(oTemp.1, ".dll\")
						oTemp.1 := RegExReplace(oTemp.1, "i)\Q.dll\\E", "\")
				}
				continue
			}
			if (A_Index & 1) ;A_Index is an odd number
			{
				oTemp[A_Index] := vArgPfx vTemp vArgSfx
				continue
			}
			vTemp := Trim(vTemp, Chr(34))
			vTemp := StrReplace(vTemp, " " , "")
			vParam := oList[vIndexParam]
			;correct case:
			vIsMatch := 0
			Loop, Parse, vListAll, % ","
				if (vTemp = A_LoopField)
				{
					vTemp := A_LoopField, vIsMatch := 1, vIndex := A_Index
					break
				}
			vParamOrig := vTemp
			if !(vParam = "")
				vTemp := vParam

			if (vParamOrig ~= "(Str|P|\*)$")
				vTemp := vParamOrig
			if vDoChangeStyleOnly && !(vTemp = vParamOrig)
				vTemp := vParamOrig

			if !vIsMatch
				vHasUnknownType := 1
			if !vIsMatch && vDoMsgUnknownType
				MsgBox, % "error: unknown parameter type:`r`n" "index: " vIndex "`r`n" "type: " vParamOrig "`r`n" vBarrier "`r`n" vTemp2 "`r`n" vBarrier "`r`n[" vTemp "]"
			if vDoStarStyle
				vTemp := RegExReplace(vTemp, "P$", "*")
			else
				vTemp := StrReplace(vTemp, "*", "P")
			if vDoQuotesStyle || InStr(vTemp, "*") || InStr(vTemp, " ")
				oTemp[A_Index] := " " Chr(34) vTemp Chr(34)
			else
				oTemp[A_Index] := " " vTemp
			vIndexParam++
		}
		if vHasUnknownType || (vListType = "")
		{
			if (StrLen(vTempOrig) > 100)
				vTempOrig := SubStr(vTempOrig, 1, 100) "..."
			oListUndefined.Push(vTempOrig)
		}
		vTemp := ""
		Loop, % oTemp.MaxIndex()-1
			vTemp .= oTemp[A_Index] ","
		vTemp .= oTemp[oTemp.MaxIndex()]
		vTemp .= ")"
		if !vHasUnknownType
			vText := SubStr(vText, 1, vPosOrig-1) vTemp SubStr(vText, vPosOrig+vLen)
		if vDoMsgBeforeAfter
			MsgBox, % "before/after:`r`n`r`n" vTempOrig "`r`n`r`n" vTemp
	}

	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, Parse, vText, `n, `r
		vOutput .= oArrayL[A_Index] A_LoopField oArrayT[A_Index] "`r`n"
	vText := oList := oTemp := ""
	if vDoMsgUnknownFunc
		MsgBox, % "count of unknown dll functions: " oListUndefined.Length()
	return SubStr(vOutput, 1, -2)
}

;==================================================

;find the point where the function ends (the closing round bracket)
;replace commas with delimiter character
JEE_FuncPrepare(ByRef vText, vPos, vDelim, ByRef vIsErrorNoEnd)
{
	local oCommaCount,oInQuote,oQuoteCount,vChar,vCharLast,vDepth,vFoundFirstBracket,vLen,vText2
	vIsErrorNoEnd := 0
	vDepth := 0
	oCommaCount := {}, oQuoteCount := {}, oInQuote := {}
	vLen := StrLen(vText)
	vText2 := ""
	VarSetCapacity(vText2, (StrLen(vText)-vPos+1)*2)
	vFoundFirstBracket := 0
	Loop
	{
		vChar := SubStr(vText, vPos, 1)
		if (vPos > vLen) || (vPos = 0)
		{
			vIsErrorNoEnd := 1
			break
		}
		vPos++
		if !vFoundFirstBracket
			if (vChar = "(")
				vFoundFirstBracket := 1
			else
			{
				vText2 .= vChar
				continue
			}
		if (vChar = Chr(34))
			oInQuote[vDepth] := !oInQuote[vDepth], oQuoteCount.HasKey(vDepth) ? oQuoteCount[vDepth] += 1 : oQuoteCount[vDepth] := 1
		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
		if (vChar = ",") && (vDepth = 1) && !oInQuote[1]
			vText2 .= vDelim
		else
			vText2 .= vChar
		if !vDepth
			break
		vCharLast := vChar
	}
	oCommaCount := oQuoteCount := oInQuote := ""
	return vText2
}

;==================================================

;find the point where the command ends (assume first CR/LF) [CHECK: improve find end]
;replace commas with delimiter character
JEE_CmdPrepare(ByRef vText, vPos, vDelim, ByRef vIsErrorNoEnd)
{
	local oCommaCount,oInQuote,oQuoteCount,vChar,vCharLast,vCharLastX,vDepth,vDoReset,vIsXpn,vLen,vPos2,vPosEnd,vText2
	vIsErrorNoEnd := 0
	vLen := StrLen(vText)
	if !vPosEnd := RegExMatch(vText, "`r|`n", "", vPos)
		vPosEnd := vLen+1
	vPosEnd--
	vText2 := SubStr(vText, vPos, vPosEnd-vPos+1)
	if RegExMatch(vText2, "^\w+[ `t]*,")
		vText2 := StrReplace(vText2, ",", vDelim, "", 1)
	else if RegExMatch(vText2, "^\w+ ")
		vText2 := StrReplace(vText2, " ", vDelim, "", 1)
	else if RegExMatch(vText2, "^\w+`t")
		vText2 := StrReplace(vText2, "`t", vDelim, "", 1)
	else
		return vText2
	vPos2 := InStr(vText2, vDelim)
	vText2 := SubStr(vText2, 1, vPos2)
	vPos += vPos2
	vCharLastX := ""
	vIsXpn := 0
	Loop
	{
		vChar := SubStr(vText, vPos, 1)
		if (vPos > vPosEnd)
		{
			vIsErrorNoEnd := 0
			break
		}
		vPos++
		if vIsXpn
		{
			if (vChar = Chr(34))
				oInQuote[vDepth] := !oInQuote[vDepth], oQuoteCount.HasKey(vDepth) ? oQuoteCount[vDepth] += 1 : oQuoteCount[vDepth] := 1
			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

			if !(vChar = " ") && !(vChar = "`t")
				vCharLastX .= vChar

			if (vChar = ",") && (vDepth = 1) && !oInQuote[1]
				vText2 .= vDelim, vCharLastX := "", vDoReset := 1
			else
				vText2 .= vChar
			;if !vDepth
			;	break
		}
		else
		{
			if !(vChar = " ") && !(vChar = "`t")
				vCharLastX .= vChar

			if (vChar = ",") && !(vCharLast = "``")
				vText2 .= vDelim, vCharLastX := ""
			else
				vText2 .= vChar
			if (vCharLastX = "%")
			&& ((vChar = " ") || (vChar = "`t"))
				vIsXpn := 1, vDoReset := 1
		}
		vCharLast := vChar
		if vDoReset
		{
			vDepth := 1
			vDoReset := 0
			oCommaCount := {}, oQuoteCount := {}, oInQuote := {}
		}
	}
	oCommaCount := oQuoteCount := oInQuote := ""
	return vText2
}

;==================================================

;using the same symbols as (except for 'e' to mean CDecl):
;WinApi
;https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
;Int i | Str s | AStr a | WStr w | Short h
;Char c | Float f | Double d | Ptr t | Int64 i6

;for PtrP: tp
;for Ptr*: t*
;for Cdecl Int: ei

;e.g. ihcti6(i) -> Int,Short,Char,Ptr,Int64,Int
;e.g. uiuhucutui6(ui) -> UInt,UShort,UChar,UPtr,UInt64,UInt
JEE_DllParamListExpand(vText, vOpt:="")
{
	static oArray := {i:"Int",s:"Str",a:"AStr",w:"WStr",h:"Short",c:"Char",f:"Float",d:"Double",t:"Ptr",6:"Int64",e:"Cdecl "}
	static oArray2 := {i:"Int",s:"Ptr",a:"Ptr",w:"Ptr",h:"Short",c:"Char",f:"Float",d:"Double",t:"Ptr",6:"Int64",e:"Cdecl "}
	local oList,vOutput,vSfx
	vText := StrReplace(vText, "i6", "6")
	vText := StrReplace(vText, "(")
	vText := StrReplace(vText, ")")
	InStr(vOpt, "x") && (vSfx := "2", vText := RegExReplace(vText, ".[p*]", "t"))
	Loop, Parse, vText
		vOutput .= (A_LoopField = "u") ? "U" : oArray%vSfx%[A_LoopField] ","
	vOutput := RegExReplace(vOutput, ",p", "P") ;RegExReplace is case sensitive
	vOutput := StrReplace(vOutput, ",*", "*")
	vOutput := StrReplace(vOutput, "Cdecl ,", "Cdecl ")
	vOutput := RTrim(vOutput, ",")
	oList := StrSplit(vOutput, ",")
	oList.Summary := vOutput
	return oList
}

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

28 Sep 2017, 16:10

Here is a script that uses JEE_FuncPrepare (see post above), to list NumGet/NumPut lines.

Code: Select all

q:: ;list NumGet/NumPut lines
FileRead, vText, % A_ScriptFullPath

;vNeedle := "NumGet("
vNeedle := "NumPut("
vOutput := ""
VarSetCapacity(vOutput, StrLen(vText)*2)
vPos := 0
Loop
{
	vPos++
	if !vPos := InStr(vText, vNeedle, 0, vPos)
		break
	if (vPos > 1) && RegExMatch(SubStr(vText, vPos-1, 1), "\w")
		continue
	vText2 := JEE_FuncPrepare(vText, vPos, Chr(1), vIsErrorNoEnd)
	if vIsErrorNoEnd
	{
		MsgBox, % "error`r`n" SubStr(vText2, 1, 200)
		continue
	}
	oTemp := StrSplit(SubStr(vText2, StrLen(vNeedle)+1), Chr(1))
	StrReplace(vText2, "`n", "", vCount)
	if (vCount < 16)
		vOutput .= oTemp.Length() "`t" StrReplace(vText2, Chr(1), ",") "`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Notus
Posts: 7
Joined: 14 Jun 2016, 19:58

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

28 Sep 2017, 22:58

This is really useful. Thank you for the great script + sharing it!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible)

05 Nov 2017, 16:50

I've done some updates.

Code: Select all

;==================================================

;e.g.
;FileRead, vText, % A_ScriptFullPath
;vOutput := JEE_TidyDllCall(vText, "np", oListUndefined)
;MsgBox, % oListUndefined.Length()
;JEE_WinMergeCompareStrings(vText, vOutput)
;return

;JEE_TidyDllCall requires JEE_FuncPrepare and JEE_DllParamListExpand

;styles: dll name:
;DllCall("Func", T1,A1, T2,A2, RT) ;omit when possible (comctl32/gdi32/kernel32/user32)
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;always show ;DEFAULT

;styles: dll name (extension):
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;DEFAULT
;DllCall("Dll.dll\Func", T1,A1, T2,A2, RT)

;styles: return parameter:
;DllCall("Dll\Func", T1,A1, T2,A2) ;omit when possible (Int) ;DEFAULT
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;always show

;styles: parameters: spacing:
;DllCall("Dll\Func", T1,A1, T2,A2, RT) ;DEFAULT
;DllCall("Dll\Func", T1, A1, T2, A2, RT)

;styles: parameters: double quotes:
;Int ;DEFAULT
;"Int"

;styles: parameters:
;IntP or "IntP" ;DEFAULT
;"Int*"

;vOpt:
;n: always include dll name (else omit comctl32/gdi32/kernel32/user32)
;x: always include .dll e.g. 'DllName.dll\Func' (else 'DllName\Func')
;r: always include return type (else omit Int)
;p: use pair style e.g. 'T1,A1, T2,A2' (else 'T1, A1, T2, A2')
;q: use quotes style e.g. "Int" (else Int)
;s: use star style e.g. Int* (else IntP)

;z: adjust style, not content: do not try to edit the function name, or change/remove parameter types (tidy parameter types, and parameter grouping)
;d1/d2/d3: diagnostic modes (show MsgBox)

;note: when creating a list of definitions,
;if 'DllName\FuncA' or 'DllName\FuncW' is defined,
;then 'DllName\Func' will also be defined if it doesn't exist
;however if 'DllName\FuncA' is defined,
;then 'DllName\FuncW' will not also be defined if it doesn't exist
;(and similarly for 'FuncW', not defining 'FuncA')

JEE_TidyDllCall(vText, vOpt:="np", ByRef oListUndefined:="")
{
	static vIsV1 := !!SubStr(1,0)
	static vDQ := Chr(34)
	static vBarrier := "=================================================="
	static vIsInit := 0, oDllInfo := {}, oDllName := {}
	static vList := "Ptr,Int64,Int,Short,Char,Float,Double"
	static vListU := "UPtr,UInt64,UInt,UShort,UChar"
	static vListC := "Cdecl Ptr,Cdecl Int64,Cdecl Int,Cdecl Short,Cdecl Char,Cdecl Float,Cdecl Double"
	static vListCU := "Cdecl UPtr,Cdecl UInt64,Cdecl UInt,Cdecl UShort,Cdecl UChar"
	static vListP := "PtrP,Int64P,IntP,ShortP,CharP,FloatP,DoubleP"
	static vListPU := "UPtrP,UInt64P,UIntP,UShortP,UCharP"
	static vListA := "Ptr*,Int64*,Int*,Short*,Char*,Float*,Double*"
	static vListAU := "UPtr*,UInt64*,UInt*,UShort*,UChar*"
	static vListS := "Str,AStr,WStr"
	static vListPtr := vListP "," vListPU "," vListA "," vListAP "," vListS
	static vListAll := vList "," vListU "," vListPtr "," vListC "," vListCU
	static vListPtr2 := "i)^(" StrReplace(StrReplace(vListPtr, ",", "|"), "*", "\*") ")$"
	local oArrayL,oArrayT,oList
	local oTemp,oTempName,vAddDllExt,vAddDllNameCGKU,vAddRetTypeInt,vArgPfx,vArgSfx,vCount,vCountFull,vCountParam,vDoChangeStyleOnly,vDoMsgBeforeAfter,vDoMsgUnknownFunc,vDoMsgUnknownType,vDoPairStyle,vDoQuotesStyle,vDoStarStyle,vErrorNoEnd,vHasUnknownType,vIndex,vIndexParam,vIsConSec,vIsMatch,vLen,vListDllFunc,vListType,vNoName,vOutput,vParam,vParamOrig,vPos,vPosOrig,vPrompt,vSfx,vTemp,vTemp2,vTempOrig,vTempX,vTypePfx,vTypeSfx,vUnused,vWithExt

	vAddDllNameCGKU := !!InStr(vOpt, "n")
	vAddDllExt := !!InStr(vOpt, "x")
	vAddRetTypeInt := !!InStr(vOpt, "r")
	vDoPairStyle := !!InStr(vOpt, "p")
	vDoQuotesStyle := !!InStr(vOpt, "q")
	vDoStarStyle := !!InStr(vOpt, "s")
	vDoChangeStyleOnly := !!InStr(vOpt, "z")
	;vTypePfx := " ", vTypeSfx := ""
	vArgPfx := vDoPairStyle?"":" ",	vArgSfx := ""

	vDoMsgBeforeAfter := !!InStr(vOpt, "d1") ;diagnostic
	vDoMsgUnknownFunc := !!InStr(vOpt, "d2") ;diagnostic
	vDoMsgUnknownType := !!InStr(vOpt, "d3") ;diagnostic

	;STAGE - prepare list of dll functions + parameters
	if !vIsInit
	{
		vIsInit := 1
		vListDllFunc := JEE_TidyDllCallGetList()
		Loop, Parse, vListDllFunc, `n
		{
			oTemp := StrSplit(A_LoopField, "=")
			if !(oTemp.Length() = 2)
				continue
			vWithExt := StrReplace(oTemp.1, "\", ".dll\")
			vNoName := RegExReplace(oTemp.1, "^.*\\")
			oDllName[oTemp.1] := oTemp.1
			oDllName[vWithExt] := vWithExt
			oDllName[vNoName] := vNoName
			oDllInfo[oTemp.1] := oTemp.2 ;Dll\Func
			oDllInfo[vWithExt] := oTemp.2 ;Dll.dll\Func
			oDllInfo[vNoName] := oTemp.2 ;Func
			if RegExMatch(oTemp.1, "(A|W)$")
			{
				oTempName := [SubStr(oTemp.1, 1, -1), SubStr(vWithExt, 1, -1), SubStr(vNoName, 1, -1)]
				Loop, 3
				{
					if oDllInfo.HasKey(oTempName[A_Index])
						continue
					oDllInfo[oTempName[A_Index]] := oTemp.2
					oDllName[oTempName[A_Index]] := oTempName[A_Index]
				}
			}
		}
		oDllInfo[""] := ""
	}
	;for vKey, vValue in oDllInfo
	;	vOutput .= vKey " " vValue "`r`n"
	;MsgBox, % Clipboard := vOutput

	;==============================

	;STAGE - remove leading whitespace, comments, continuation sections
	StrReplace(vText, "`n", "", vCount)
	(oArrayL := {}).SetCapacity(vCount+1)
	(oArrayT := {}).SetCapacity(vCount+1)
	oListUndefined := {}
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, Parse, vText, `n, `r
	{
		vTemp := A_LoopField
		if (vPos := RegExMatch(vTemp, "^;|[ `t];"))
		{
			oArrayT[A_Index] := SubStr(vTemp, vPos)
			vTemp := SubStr(vTemp, 1, vPos-1)
		}
		if (SubStr(LTrim(vTemp), 1, 1) = ")")
			vIsConSec := 0
		if vIsConSec
		{
			oArrayL[A_Index] := vTemp
			vOutput .= "`n"
			continue
		}
		if (vPos := RegExMatch(vTemp, "[ `t]*\K"))
		{
			oArrayL[A_Index] := SubStr(vTemp, 1, vPos-1)
			vTemp := SubStr(vTemp, vPos)
		}
		if !vIsConSec && (SubStr(vTemp, 1, 1) = "(") && !InStr(vTemp, ")")
			vIsConSec := 1
		vOutput .= vTemp "`n"
	}
	vText := SubStr(vOutput, 1, -1)

	;vUnused := JEE_StrUnused(vText)
	vUnused := Chr(1)
	if InStr(vText, vUnused)
	{
		MsgBox, % "error: no available unused character found"
		return
	}

	;==============================

	;STAGE - find each occurrence of DllCall and convert it
	vPosOrig := 0
	Loop
	{
		vPos := InStr(vText, "DllCall(", 0, vPosOrig+1)
		if !vPos
			break
		vPosOrig := vPos
		if (vPos > 1) && RegExMatch(SubStr(vText, vPos-1, 1), "[\w\x22]")
			continue
		;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
		vTemp2 := JEE_FuncPrepare(vText, vPos, vUnused, vErrorNoEnd)
		if vErrorNoEnd
		{
			MsgBox, % "warning: no end of DllCall line found"
			continue
		}
		vTemp := StrReplace(vTemp2, vUnused, ",")
		vLen := StrLen(vTemp2)
		vTempOrig := vTemp
		if (SubStr(vTemp2, vIsV1-1) = ")")
			vTemp2 := SubStr(vTemp2, 1, -1)
		oTemp := StrSplit(vTemp2, vUnused)
		oTemp.1 := RegExReplace(oTemp.1, "DllCall\(\K[ `t]*")
		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)

		;ignore certain dll name strings
		if (SubStr(vTempX, 1, 7) = "NumGet(")
			continue
		vTempX := StrReplace(vTempX, "(A_IsUnicode?" vDQ "W" vDQ ":" vDQ "A" vDQ ")") ;(A_IsUnicode?"W":"A")
		vTempX := StrReplace(vTempX, "(A_PtrSize=8?" vDQ "Ptr" vDQ ":" vDQ vDQ ")") ;(A_PtrSize=8?"Ptr":"")
		vTempX := StrReplace(vTempX, " vSfx")
		vTempX := Trim(vTempX)
		if (SubStr(vTempX, 1, 1) = Chr(34)) && (SubStr(vTempX, vIsV1-1) = Chr(34))
			vTempX := SubStr(vTempX, 2, -1)
		vListType := oDllInfo[vTempX]
		if !vDoChangeStyleOnly
		{
			if (vTempX = oDllName[vTempX])
				oTemp.1 := StrReplace(oTemp.1, vTempX, oDllName[vTempX])
		}
		oList := JEE_DllParamListExpand(vListType)
		vCountFull := oList.Length()*2
		if !vDoChangeStyleOnly
		{
			if (vCountParam = vCountFull-1)
			&& (!(oList[oList.MaxIndex()] = "Int") || vAddRetTypeInt)
				oTemp[oTemp.MaxIndex()+1] := oList[oList.MaxIndex()]
			if (vCountParam = vCountFull)
			&& (oList[oList.MaxIndex()] = "Int") && !vAddRetTypeInt
				oTemp.Pop()
		}

		;==================================================

		;STAGE - convert parameter types
		vHasUnknownType := 0
		vIndexParam := 1
		Loop, % oTemp.MaxIndex()
		{
			vTemp := Trim(oTemp[A_Index])
			if (A_Index = 1)
			{
				if !vDoChangeStyleOnly && vAddDllNameCGKU
				{
					vTemp := Trim(SubStr(oTemp.1, 9), Chr(34))
					if !InStr(vTemp, "\") && !InStr(vTemp, " ")
						Loop, Parse, % "comctl|gdi|kernel|user", |
							if oDllName.HasKey(A_LoopField "32\" vTemp)
								oTemp.1 := "DllCall(" Chr(34) A_LoopField "32\" vTemp Chr(34)
				}
				else if !vDoChangeStyleOnly
					oTemp.1 := RegExReplace(oTemp[1], "i)\x22\K(comctl|gdi|kernel|user)32(.dll)?\\")
				if !vDoChangeStyleOnly && vAddDllExt
				{
					if InStr(oTemp.1, "\") && !InStr(oTemp.1, ".dll\")
						oTemp.1 := StrReplace(oTemp.1, "\", ".dll\")
				}
				else if !vDoChangeStyleOnly
				{
					if InStr(oTemp.1, "\") && InStr(oTemp.1, ".dll\")
						oTemp.1 := RegExReplace(oTemp.1, "i)\Q.dll\\E", "\")
				}
				continue
			}
			if (A_Index & 1) ;A_Index is an odd number
			{
				oTemp[A_Index] := vArgPfx vTemp vArgSfx
				continue
			}
			vTemp := Trim(vTemp, Chr(34))
			vTemp := Trim(vTemp)
			if !InStr(vTemp, "Cdecl")
				vTemp := StrReplace(vTemp, " ")
			vParam := oList[vIndexParam]
			;correct case:
			vIsMatch := 0
			if vDoStarStyle
				vTemp := RegExReplace(vTemp, "P$", "*")
			else
				vTemp := StrReplace(vTemp, "*", "P")
			Loop, Parse, vListAll, % ","
				if (vTemp = A_LoopField)
				{
					vTemp := A_LoopField, vIsMatch := 1, vIndex := A_Index
					break
				}
			vParamOrig := vTemp
			if !(vParam = "")
				vTemp := vParam

			if (vParamOrig ~= "(Str|P|\*)$") || (vParamOrig = "vPtrType")
				vTemp := vParamOrig
			if vDoChangeStyleOnly && !(vTemp = vParamOrig)
				vTemp := vParamOrig

			if !vIsMatch && (vTemp = "vPtrType")
				vIsMatch := 1
			if !vIsMatch
				vHasUnknownType := 1
			if !vIsMatch && vDoMsgUnknownType
				MsgBox, % "error: unknown parameter type:`r`n" "index: " vIndex "`r`n" "type: " vParamOrig "`r`n" vBarrier "`r`n" vTemp2 "`r`n" vBarrier "`r`n[" vTemp "]"
			if vDoQuotesStyle || InStr(vTemp, "*") || InStr(vTemp, " ")
				oTemp[A_Index] := " " Chr(34) vTemp Chr(34)
			else
				oTemp[A_Index] := " " vTemp
			vIndexParam++
		}
		if vHasUnknownType || (vListType = "")
		{
			if (StrLen(vTempOrig) > 300)
				vTempOrig := SubStr(vTempOrig, 1, 300) "..."
			oListUndefined.Push(vTempOrig)
		}
		vTemp := ""
		Loop, % oTemp.MaxIndex()-1
			vTemp .= oTemp[A_Index] ","
		vTemp .= oTemp[oTemp.MaxIndex()]
		vTemp .= ")"
		if !vHasUnknownType
			vText := SubStr(vText, 1, vPosOrig-1) vTemp SubStr(vText, vPosOrig+vLen)
		if vDoMsgBeforeAfter
			MsgBox, % "before/after:`r`n`r`n" vTempOrig "`r`n`r`n" vTemp
	}

	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, Parse, vText, `n, `r
		vOutput .= oArrayL[A_Index] A_LoopField oArrayT[A_Index] "`r`n"
	vText := oList := oTemp := ""
	if vDoMsgUnknownFunc
		MsgBox, % "count of unknown dll functions: " oListUndefined.Length()
	return SubStr(vOutput, 1, -2)
}

;==================================================

;find the point where the function ends (the closing round bracket)
;replace commas with delimiter character
JEE_FuncPrepare(ByRef vText, vPos, vDelim, ByRef vIsErrorNoEnd)
{
	local oCommaCount,oInQuote,oQuoteCount,vChar,vCharLast,vDepth,vFoundFirstBracket,vLen,vText2
	vIsErrorNoEnd := 0
	vDepth := 0
	oCommaCount := {}, oQuoteCount := {}, oInQuote := {}
	vLen := StrLen(vText)
	vText2 := ""
	VarSetCapacity(vText2, (StrLen(vText)-vPos+1)*2)
	vFoundFirstBracket := 0
	Loop
	{
		vChar := SubStr(vText, vPos, 1)
		if (vPos > vLen) || (vPos = 0)
		{
			vIsErrorNoEnd := 1
			break
		}
		vPos++
		if !vFoundFirstBracket
			if (vChar = "(")
				vFoundFirstBracket := 1
			else
			{
				vText2 .= vChar
				continue
			}
		if (vChar = Chr(34))
			oInQuote[vDepth] := !oInQuote[vDepth], oQuoteCount.HasKey(vDepth) ? oQuoteCount[vDepth] += 1 : oQuoteCount[vDepth] := 1
		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
		if (vChar = ",") && (vDepth = 1) && !oInQuote[1]
			vText2 .= vDelim
		else
			vText2 .= vChar
		if !vDepth
			break
		vCharLast := vChar
	}
	oCommaCount := oQuoteCount := oInQuote := ""
	return vText2
}

;==================================================

;find the point where the command ends (assume first CR/LF) [CHECK: improve find end]
;replace commas with delimiter character
JEE_CmdPrepare(ByRef vText, vPos, vDelim, ByRef vIsErrorNoEnd)
{
	local oCommaCount,oInQuote,oQuoteCount,vChar,vCharLast,vCharLastX,vDepth,vDoReset,vIsXpn,vLen,vPos2,vPosEnd,vText2
	vIsErrorNoEnd := 0
	vLen := StrLen(vText)
	if !vPosEnd := RegExMatch(vText, "`r|`n", "", vPos)
		vPosEnd := vLen+1
	vPosEnd--
	vText2 := SubStr(vText, vPos, vPosEnd-vPos+1)
	if RegExMatch(vText2, "^\w+[ `t]*,")
		vText2 := StrReplace(vText2, ",", vDelim, "", 1)
	else if RegExMatch(vText2, "^\w+ ")
		vText2 := StrReplace(vText2, " ", vDelim, "", 1)
	else if RegExMatch(vText2, "^\w+`t")
		vText2 := StrReplace(vText2, "`t", vDelim, "", 1)
	else
		return vText2
	vPos2 := InStr(vText2, vDelim)
	vText2 := SubStr(vText2, 1, vPos2)
	vPos += vPos2
	vCharLastX := ""
	vIsXpn := 0
	Loop
	{
		vChar := SubStr(vText, vPos, 1)
		if (vPos > vPosEnd)
		{
			vIsErrorNoEnd := 0
			break
		}
		vPos++
		if vIsXpn
		{
			if (vChar = Chr(34))
				oInQuote[vDepth] := !oInQuote[vDepth], oQuoteCount.HasKey(vDepth) ? oQuoteCount[vDepth] += 1 : oQuoteCount[vDepth] := 1
			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

			if !(vChar = " ") && !(vChar = "`t")
				vCharLastX .= vChar

			if (vChar = ",") && (vDepth = 1) && !oInQuote[1]
				vText2 .= vDelim, vCharLastX := "", vDoReset := 1
			else
				vText2 .= vChar
			;if !vDepth
			;	break
		}
		else
		{
			if !(vChar = " ") && !(vChar = "`t")
				vCharLastX .= vChar

			if (vChar = ",") && !(vCharLast = "``")
				vText2 .= vDelim, vCharLastX := ""
			else
				vText2 .= vChar
			if (vCharLastX = "%")
			&& ((vChar = " ") || (vChar = "`t"))
				vIsXpn := 1, vDoReset := 1
		}
		vCharLast := vChar
		if vDoReset
		{
			vDepth := 1
			vDoReset := 0
			oCommaCount := {}, oQuoteCount := {}, oInQuote := {}
		}
	}
	oCommaCount := oQuoteCount := oInQuote := ""
	return vText2
}

;==================================================

;using the same symbols as WinApi.htm (except for 'e' to mean Cdecl, and 'l' to mean TCHAR):
;HotKeyIt: acdfhistvwxyz, u
;me: l, e
;unused: bgjkmnopqr

;WinApi
;https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
;Int i | Str s | AStr a | WStr w | Short h
;Char c | Float f | Double d | Ptr t | Int64 i6

;for PtrP: tp
;for Ptr*: t*
;for Cdecl Int: ei

;e.g. ihcti6(i) -> Int,Short,Char,Ptr,Int64,Int
;e.g. uiuhucutui6(ui) -> UInt,UShort,UChar,UPtr,UInt64,UInt
JEE_DllParamListExpand(vText, vOpt:="")
{
	static oArray := {i:"Int",s:"Str",a:"AStr",w:"WStr",h:"Short",c:"Char",f:"Float",d:"Double",t:"Ptr",6:"Int64",e:"Cdecl "}
	static oArray2 := {i:"Int",s:"Ptr",a:"Ptr",w:"Ptr",h:"Short",c:"Char",f:"Float",d:"Double",t:"Ptr",6:"Int64",e:"Cdecl "}
	local oList,vOutput,vIs64,vIsW,vSfx
	if (vText ~= "[lvxyz]")
	{
		vOpt := (A_IsUnicode?"w":"a") (A_PtrSize=8?64:32) vOpt
		vIsW := InStr(vOpt, "w") > InStr(vOpt, "a")
		vIs64 := InStr(vOpt, "64") > InStr(vOpt, "32")
		vText := StrReplace(vText, "l", vIsW?"uh":"c")
		vText := StrReplace(vText, "v", vIs64?"i":"h")
		vText := StrReplace(vText, "x", vIs64?"ui":"uh")
		vText := StrReplace(vText, "y", vIsW?"h":"c")
		vText := StrReplace(vText, "z", vIsW?"uh":"uc")
	}
	vText := StrReplace(vText, "i6", "6")
	vText := StrReplace(vText, "(")
	vText := StrReplace(vText, ")")
	InStr(vOpt, "x") && (vSfx := "2", vText := RegExReplace(vText, ".[p*]", "t"))
	Loop, Parse, vText
		vOutput .= (A_LoopField = "u") ? "U" : oArray%vSfx%[A_LoopField] ","
	vOutput := RegExReplace(vOutput, ",p", "P") ;RegExReplace is case sensitive
	vOutput := StrReplace(vOutput, ",*", "*")
	vOutput := StrReplace(vOutput, "Cdecl ,", "Cdecl ")
	vOutput := RTrim(vOutput, ",")
	oList := StrSplit(vOutput, ",")
	oList.Summary := vOutput
	return oList
}

;==================================================

JEE_TidyDllCallGetList()
{
	;note: edited GetClassLong/SetClassLong to be 'ut' not 'ui'
	;note: edited GetWindowLong/SetWindowLong to be 't' not 'i'
	;dll list - start

	;the first 2 variables include functions from these dlls:
	;WinApi
	;https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
	;Advapi32.dll, Comctl32.dll, Comdlg32.dll, Crypt32.dll, Gdi32.dll, Gdiplus.dll, Glu32.dll, Hid.dll, Kernel32.dll, Ole32.dll, Oleacc.dll, OleAut32.dll, Opengl32.dll, Rasapi32.dll, Rasdlg.dll, Rasman.dll, Shell32.dll, Shlwapi.dll, Tapi32.dll, User32.dll, Userenv.dll, UxTheme.dll, Version.dll, Winhttp.dll, Wininet.dll, Winmm.dll, Ws2_32.dll
	vListDllFunc1 = ;continuation section
	(LTrim
	advapi32\AdjustTokenPrivileges=tituitt(i)
	advapi32\CloseServiceHandle=t(i)
	advapi32\CryptAcquireContextA=tttuiui(i)
	advapi32\CryptAcquireContextW=tttuiui(i)
	advapi32\CryptCreateHash=utuiutuit(i)
	advapi32\CryptDestroyHash=ut(i)
	advapi32\CryptGetHashParam=utuittui(i)
	advapi32\CryptHashData=uttuiui(i)
	advapi32\CryptReleaseContext=utui(i)
	advapi32\GetUserName=tt(i)
	advapi32\GetUserNameA=tt(i)
	advapi32\GetUserNameW=tt(i)
	advapi32\IsTextUnicode=tit(i)
	advapi32\LockServiceDatabase=t(t)
	advapi32\LookupPrivilegeValueA=ttt(i)
	advapi32\LookupPrivilegeValueW=ttt(i)
	advapi32\OpenEventLog=tt(t)
	advapi32\OpenEventLogA=tt(t)
	advapi32\OpenEventLogW=tt(t)
	advapi32\OpenProcessToken=tuit(i)
	advapi32\OpenSCManager=ttui(t)
	advapi32\OpenSCManagerA=ttui(t)
	advapi32\OpenSCManagerW=ttui(t)
	advapi32\ReadEventLog=tuiuituitt(i)
	advapi32\ReadEventLogA=tuiuituitt(i)
	advapi32\ReadEventLogW=tuiuituitt(i)
	advapi32\RegCloseKey=t(i)
	advapi32\RegEnumKeyEx=tuitttttt(i)
	advapi32\RegEnumKeyExA=tuitttttt(i)
	advapi32\RegEnumKeyExW=tuitttttt(i)
	advapi32\RegEnumValue=tuitttttt(i)
	advapi32\RegEnumValueA=tuitttttt(i)
	advapi32\RegEnumValueW=tuitttttt(i)
	advapi32\RegOpenKeyExA=ttuiuit(i)
	advapi32\RegOpenKeyExW=ttuiuit(i)
	advapi32\RegQueryInfoKeyA=tttttttttttt(i)
	advapi32\RegQueryInfoKeyW=tttttttttttt(i)
	advapi32\RegQueryValueExA=tttttt(i)
	advapi32\RegQueryValueExW=tttttt(i)
	advapi32\UnlockServiceDatabase=t(i)
	comctl32\ImageList_Add=ttt(i)
	comctl32\ImageList_Create=iiuiii(t)
	comctl32\ImageList_Replace=titt(i)
	comctl32\ImageList_ReplaceIcon=tit(i)
	comctl32\InitCommonControlsEx=t(i)
	comdlg32\GetFileTitle=ttuh(h)
	comdlg32\GetFileTitleA=ttuh(h)
	comdlg32\GetFileTitleW=ttuh(h)
	crypt32\CryptBinaryToString=tuiuitt(i)
	crypt32\CryptBinaryToStringA=tuiuitt(i)
	crypt32\CryptBinaryToStringW=tuiuitt(i)
	crypt32\CryptStringToBinary=tuiuitttt(i)
	crypt32\CryptStringToBinaryA=tuiuitttt(i)
	crypt32\CryptStringToBinaryW=tuiuitttt(i)
	gdi32\BitBlt=tiiiitiiui(i)
	gdi32\CreateBitmap=iiuiuit(t)
	gdi32\CreateBitmapIndirect=t(t)
	gdi32\CreateCompatibleBitmap=tii(t)
	gdi32\CreateCompatibleDC=t(t)
	gdi32\CreateDIBSection=ttuittui(t)
	gdi32\CreateFontA=iiiiiuiuiuiuiuiuiuiuit(t)
	gdi32\CreateFontIndirectA=t(t)
	gdi32\CreateFontIndirectW=t(t)
	gdi32\CreateFontW=iiiiiuiuiuiuiuiuiuiuit(t)
	gdi32\CreatePen=iiui(t)
	gdi32\CreateSolidBrush=ui(t)
	gdi32\DeleteDC=t(i)
	gdi32\DeleteEnhMetaFile=t(i)
	gdi32\DeleteObject=t(i)
	gdi32\GetCurrentObject=tui(t)
	gdi32\GetDeviceCaps=ti(i)
	gdi32\GetDeviceGammaRamp=tt(i)
	gdi32\GetDIBits=ttuiuittui(i)
	gdi32\GetEnhMetaFileBits=tuit(ui)
	gdi32\GetFontUnicodeRanges=tt(ui)
	gdi32\GetObjectA=tit(i)
	gdi32\GetObjectType=t(ui)
	gdi32\GetObjectW=tit(i)
	gdi32\GetStockObject=i(t)
	gdi32\GetTextExtentPoint32=ttit(i)
	gdi32\GetTextExtentPoint32A=ttit(i)
	gdi32\GetTextExtentPoint32W=ttit(i)
	gdi32\GetTextFaceA=tit(i)
	gdi32\GetTextFaceW=tit(i)
	gdi32\GetTextMetrics=tt(i)
	gdi32\GetTextMetricsA=tt(i)
	gdi32\GetTextMetricsW=tt(i)
	gdi32\RealizePalette=t(ui)
	gdi32\Rectangle=tiiii(i)
	gdi32\SelectObject=tt(t)
	gdi32\SelectPalette=tti(t)
	gdi32\SetBkColor=tui(ui)
	gdi32\SetDeviceGammaRamp=tt(i)
	gdi32\SetDIBColorTable=tuiuit(ui)
	gdi32\SetEnhMetaFileBits=uit(t)
	gdi32\SetStretchBltMode=ti(i)
	gdi32\SetTextColor=tui(ui)
	gdi32\StretchBlt=tiiiitiiiiui(i)
	gdiplus\GdipBitmapGetPixel=tiit(i)
	gdiplus\GdipCreateBitmapFromHBITMAP=ttt(i)
	gdiplus\GdipCreateBitmapFromStream=tt(i)
	gdiplus\GdipCreateHBITMAPFromBitmap=ttui(i)
	gdiplus\GdipDisposeImage=t(i)
	gdiplus\GdipGetImageHeight=tt(i)
	gdiplus\GdipGetImageWidth=tt(i)
	gdiplus\GdiplusShutdown=ut(i)
	gdiplus\GdiplusStartup=uttt(i)
	kernel32\AllocConsole=(i)
	kernel32\AttachConsole=ui(i)
	kernel32\Beep=uiui(i)
	kernel32\CloseHandle=t(i)
	kernel32\CreateFileA=tuiuituiuit(t)
	kernel32\CreateFileW=tuiuituiuit(t)
	kernel32\CreateProcessA=ttttiuitttt(i)
	kernel32\CreateProcessW=ttttiuitttt(i)
	kernel32\CreateRemoteThread=ttutttuit(t)
	kernel32\CreateToolhelp32Snapshot=uiui(t)
	kernel32\DeleteFileA=t(i)
	kernel32\DeleteFileW=t(i)
	kernel32\DeviceIoControl=tuituituitt(i)
	kernel32\ExpandEnvironmentStringsA=ttui(ui)
	kernel32\ExpandEnvironmentStringsW=ttui(ui)
	kernel32\FileTimeToLocalFileTime=tt(i)
	kernel32\FileTimeToSystemTime=tt(i)
	kernel32\FindClose=t(i)
	kernel32\FindFirstFileA=tt(t)
	kernel32\FindFirstFileW=tt(t)
	kernel32\FindNextFileA=tt(i)
	kernel32\FindNextFileW=tt(i)
	kernel32\FindResourceA=ttt(t)
	kernel32\FindResourceW=ttt(t)
	kernel32\FormatMessage=uituiuituit(ui)
	kernel32\FormatMessageA=uituiuituit(ui)
	kernel32\FormatMessageW=uituiuituit(ui)
	kernel32\FreeConsole=(i)
	kernel32\FreeLibrary=t(i)
	kernel32\GetACP=(ui)
	kernel32\GetCommandLineA=(t)
	kernel32\GetCommandLineW=(t)
	kernel32\GetComputerName=tt(i)
	kernel32\GetComputerNameA=tt(i)
	kernel32\GetComputerNameW=tt(i)
	kernel32\GetCurrentDirectory=uit(ui)
	kernel32\GetCurrentDirectoryA=uit(ui)
	kernel32\GetCurrentDirectoryW=uit(ui)
	kernel32\GetCurrentProcessId=(ui)
	kernel32\GetCurrentThreadId=(ui)
	kernel32\GetDateFormat=uiuittti(i)
	kernel32\GetDateFormatA=uiuittti(i)
	kernel32\GetDateFormatW=uiuittti(i)
	kernel32\GetDiskFreeSpaceExA=tttt(i)
	kernel32\GetDiskFreeSpaceExW=tttt(i)
	kernel32\GetEnvironmentVariableA=ttui(ui)
	kernel32\GetEnvironmentVariableW=ttui(ui)
	kernel32\GetExitCodeThread=tt(i)
	kernel32\GetFileAttributesA=t(ui)
	kernel32\GetFileAttributesW=t(ui)
	kernel32\GetFileSizeEx=tt(i)
	kernel32\GetFileTime=tttt(i)
	kernel32\GetFullPathNameA=tuitt(ui)
	kernel32\GetFullPathNameW=tuitt(ui)
	kernel32\GetLastError=(ui)
	kernel32\GetLocalTime=t(i)
	kernel32\GetLogicalDrives=(ui)
	kernel32\GetLogicalDriveStringsA=uit(ui)
	kernel32\GetLogicalDriveStringsW=uit(ui)
	kernel32\GetLongPathNameA=ttui(ui)
	kernel32\GetLongPathNameW=ttui(ui)
	kernel32\GetModuleBaseName=tttui(ui)
	kernel32\GetModuleFileNameA=ttui(ui)
	kernel32\GetModuleFileNameW=ttui(ui)
	kernel32\GetModuleHandleA=t(t)
	kernel32\GetModuleHandleW=t(t)
	kernel32\GetNativeSystemInfo=t(i)
	kernel32\GetPriorityClass=t(ui)
	kernel32\GetProcAddress=tt(t)
	kernel32\GetProcessImageFileName=ttui(ui)
	kernel32\GetProcessTimes=ttttt(i)
	kernel32\GetShortPathNameA=ttui(ui)
	kernel32\GetShortPathNameW=ttui(ui)
	kernel32\GetStdHandle=ui(t)
	kernel32\GetSystemDefaultUILanguage=(uh)
	kernel32\GetSystemInfo=t(i)
	kernel32\GetSystemPowerStatus=t(i)
	kernel32\GetSystemTime=t(i)
	kernel32\GetSystemTimeAsFileTime=t(i)
	kernel32\GetSystemWow64Directory=tui(ui)
	kernel32\GetSystemWow64DirectoryA=tui(ui)
	kernel32\GetSystemWow64DirectoryW=tui(ui)
	kernel32\GetTempFileNameA=ttuit(ui)
	kernel32\GetTempFileNameW=ttuit(ui)
	kernel32\GetTempPath=uit(ui)
	kernel32\GetTempPathA=uit(ui)
	kernel32\GetTempPathW=uit(ui)
	kernel32\GetTickCount=(ui)
	kernel32\GetTimeFormat=uiuittti(i)
	kernel32\GetTimeFormatA=uiuittti(i)
	kernel32\GetTimeFormatW=uiuittti(i)
	kernel32\GetTimeZoneInformation=t(ui)
	kernel32\GetTimeZoneInformationForYear=uhtt(i)
	kernel32\GetVersion=(ui)
	kernel32\GetVersionExA=t(i)
	kernel32\GetVersionExW=t(i)
	kernel32\GetWindowsDirectory=tui(ui)
	kernel32\GetWindowsDirectoryA=tui(ui)
	kernel32\GetWindowsDirectoryW=tui(ui)
	kernel32\GlobalAlloc=uiut(t)
	kernel32\GlobalFree=t(t)
	kernel32\GlobalLock=t(t)
	kernel32\GlobalSize=t(ut)
	kernel32\GlobalUnlock=t(i)
	kernel32\IsWow64Process=tt(i)
	kernel32\LCMapStringA=uiuititi(i)
	kernel32\LCMapStringW=uiuititi(i)
	kernel32\LoadLibrary=t(t)
	kernel32\LoadLibraryA=t(t)
	kernel32\LoadLibraryW=t(t)
	kernel32\LoadResource=tt(t)
	kernel32\LocalFileTimeToFileTime=tt(i)
	kernel32\LocalFree=t(t)
	kernel32\LockResource=t(t)
	kernel32\lstrcpy=tt(t)
	kernel32\lstrcpyA=tt(t)
	kernel32\lstrcpyn=tti(t)
	kernel32\lstrcpynA=tti(t)
	kernel32\lstrcpynW=tti(t)
	kernel32\lstrcpyW=tt(t)
	kernel32\lstrlen=t(i)
	kernel32\lstrlenA=t(i)
	kernel32\lstrlenW=t(i)
	kernel32\Module32First=tt(i)
	kernel32\Module32FirstW=tt(i)
	kernel32\Module32Next=tt(i)
	kernel32\Module32NextW=tt(i)
	kernel32\MulDiv=iii(i)
	kernel32\MultiByteToWideChar=uiuititi(i)
	kernel32\OpenProcess=uiiui(t)
	kernel32\QueryPerformanceCounter=t(i)
	kernel32\QueryPerformanceFrequency=t(i)
	kernel32\ReadFile=ttuitt(i)
	kernel32\ReadProcessMemory=tttutt(i)
	kernel32\RtlMoveMemory=ttut(i)
	kernel32\SetCurrentDirectory=t(i)
	kernel32\SetCurrentDirectoryA=t(i)
	kernel32\SetCurrentDirectoryW=t(i)
	kernel32\SetFilePointerEx=ti6tui(i)
	kernel32\SetFileTime=tttt(i)
	kernel32\SetLastError=ui(i)
	kernel32\SetPriorityClass=tui(i)
	kernel32\SetProcessShutdownParameters=uiui(i)
	kernel32\SetSystemTime=t(i)
	kernel32\SizeofResource=tt(ui)
	kernel32\Sleep=ui(i)
	kernel32\SystemTimeToFileTime=tt(i)
	kernel32\SystemTimeToTzSpecificLocalTime=ttt(i)
	kernel32\TerminateProcess=tui(i)
	kernel32\TzSpecificLocalTimeToSystemTime=ttt(i)
	kernel32\VirtualAlloc=tutuiui(t)
	kernel32\VirtualAllocEx=ttutuiui(t)
	kernel32\VirtualFreeEx=ttutui(i)
	kernel32\VirtualProtect=tutuit(i)
	kernel32\VirtualProtectEx=ttutuit(i)
	kernel32\VirtualQueryEx=tttut(ut)
	kernel32\WaitForSingleObject=tui(ui)
	kernel32\WideCharToMultiByte=uiuitititt(i)
	kernel32\Wow64DisableWow64FsRedirection=t(i)
	kernel32\WriteFile=ttuitt(i)
	kernel32\WriteProcessMemory=tttutt(i)
	)

	vListDllFunc2 = ;continuation section
	(LTrim
	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\CoInitializeEx=tui(i)
	ole32\CoTaskMemAlloc=ut(t)
	ole32\CoTaskMemFree=t(i)
	ole32\CoUninitialize=(i)
	ole32\CreateStreamOnHGlobal=tit(i)
	ole32\IIDFromString=tt(i)
	ole32\IsEqualGUID=tt(i)
	ole32\OleInitialize=t(i)
	ole32\OleUninitialize=(i)
	ole32\ProgIDFromCLSID=tt(i)
	ole32\StringFromCLSID=tt(i)
	ole32\StringFromGUID2=tti(i)
	oleacc\AccessibleChildren=tiitt(i)
	oleacc\AccessibleObjectFromEvent=tuiuitt(i)
	oleacc\AccessibleObjectFromPoint=ui6tt(i)
	oleacc\AccessibleObjectFromWindow=tuitt(i)
	oleacc\GetRoleTextA=uitui(ui)
	oleacc\GetRoleTextW=uitui(ui)
	oleacc\GetStateTextA=uitui(ui)
	oleacc\GetStateTextW=uitui(ui)
	oleacc\ObjectFromLresult=ttutt(i)
	oleacc\WindowFromAccessibleObject=tt(i)
	oleaut32\DispGetParam=tuiuhtt(i)
	oleaut32\GetActiveObject=ttt(i)
	oleaut32\SafeArrayAccessData=tt(i)
	oleaut32\SafeArrayDestroy=t(i)
	oleaut32\SafeArrayGetDim=t(ui)
	oleaut32\SafeArrayPtrOfIndex=ttt(i)
	oleaut32\SafeArrayUnaccessData=t(i)
	oleaut32\SysAllocString=t(t)
	oleaut32\SysFreeString=t(i)
	oleaut32\SysStringLen=t(ui)
	oleaut32\VariantChangeTypeEx=ttuiuhuh(i)
	oleaut32\VariantClear=t(i)
	shell32\DllGetVersion=t(i)
	shell32\DragFinish=t(i)
	shell32\DragQueryFile=tuitui(ui)
	shell32\DragQueryFileA=tuitui(ui)
	shell32\DragQueryFileW=tuitui(ui)
	shell32\ExtractIconEx=tittui(ui)
	shell32\ExtractIconExA=tittui(ui)
	shell32\ExtractIconExW=tittui(ui)
	shell32\ILClone=t(t)
	shell32\ILFree=t(i)
	shell32\ILGetSize=t(ui)
	shell32\SHAddToRecentDocs=uit(i)
	shell32\SHAppBarMessage=uit(ut)
	shell32\SHBindToParent=tttt(i)
	shell32\SHChangeNotify=iuitt(i)
	shell32\SHCreateDataObject=tuitttt(i)
	shell32\Shell_NotifyIcon=uit(i)
	shell32\Shell_NotifyIconA=uit(i)
	shell32\Shell_NotifyIconW=uit(i)
	shell32\SHFreeShared=tui(i)
	shell32\SHGetDesktopFolder=t(i)
	shell32\SHGetFileInfo=tuituiui(ut)
	shell32\SHGetFileInfoA=tuituiui(ut)
	shell32\SHGetFileInfoW=tuituiui(ut)
	shell32\SHGetFolderLocation=tituit(i)
	shell32\SHGetFolderPathA=tituit(i)
	shell32\SHGetFolderPathW=tituit(i)
	shell32\SHGetNameFromPropertyKey=tt(i)
	shell32\SHGetPathFromIDList=tt(i)
	shell32\SHGetPathFromIDListA=tt(i)
	shell32\SHGetPathFromIDListW=tt(i)
	shell32\SHGetSetSettings=tuii(i)
	shell32\SHLockShared=tui(t)
	shell32\SHMultiFileProperties=tui(i)
	shell32\SHOpenFolderAndSelectItems=tuitui(i)
	shell32\SHParseDisplayName=tttuit(i)
	shell32\SHQueryRecycleBinA=tt(i)
	shell32\SHQueryRecycleBinW=tt(i)
	shell32\SHUnlockShared=t(i)
	shlwapi\AssocQueryString=iitttt(i)
	shlwapi\AssocQueryStringA=iitttt(i)
	shlwapi\AssocQueryStringW=iitttt(i)
	shlwapi\PathCreateFromUrlA=tttui(i)
	shlwapi\PathCreateFromUrlW=tttui(i)
	shlwapi\SHGetViewStatePropertyBag=ttuitt(i)
	shlwapi\StrCmpLogicalW=tt(i)
	shlwapi\StrCmpNA=tti(i)
	shlwapi\StrCmpNW=tti(i)
	shlwapi\StrRetToBuf=tttui(i)
	shlwapi\StrRetToBufA=tttui(i)
	shlwapi\StrRetToBufW=tttui(i)
	shlwapi\StrStrIA=tt(t)
	shlwapi\StrStrIW=tt(t)
	shlwapi\UrlCreateFromPathA=tttui(i)
	shlwapi\UrlCreateFromPathW=tttui(i)
	shlwapi\UrlEscapeA=tttui(i)
	shlwapi\UrlEscapeW=tttui(i)
	shlwapi\UrlUnescapeA=tttui(i)
	shlwapi\UrlUnescapeW=tttui(i)
	user32\AppendMenuA=tuiutt(i)
	user32\AppendMenuW=tuiutt(i)
	user32\AttachThreadInput=uiuii(i)
	user32\CallNextHookEx=tiutt(t)
	user32\CallWindowProcA=ttuiutt(t)
	user32\CallWindowProcW=ttuiutt(t)
	user32\CharLowerA=t(t)
	user32\CharLowerW=t(t)
	user32\CharUpperA=t(t)
	user32\CharUpperW=t(t)
	user32\CheckMenuItem=tuiui(ui)
	user32\ClientToScreen=tt(i)
	user32\CloseClipboard=(i)
	user32\CopyIcon=t(t)
	user32\CopyImage=tuiiiui(t)
	user32\CountClipboardFormats=(i)
	user32\CreateAcceleratorTable=ti(t)
	user32\CreateAcceleratorTableA=ti(t)
	user32\CreateAcceleratorTableW=ti(t)
	user32\CreateCaret=ttii(i)
	user32\CreateCursor=tiiiitt(t)
	user32\CreateDialogParamA=ttttt(t)
	user32\CreateDialogParamW=ttttt(t)
	user32\CreateIconFromResourceEx=tuiiuiiiui(t)
	user32\CreateMenu=(t)
	user32\CreatePopupMenu=(t)
	user32\CreateWindowEx=uittuiiiiitttt(t)
	user32\CreateWindowExA=uittuiiiiitttt(t)
	user32\CreateWindowExW=uittuiiiiitttt(t)
	user32\DefWindowProcA=tuiutt(t)
	user32\DefWindowProcW=tuiutt(t)
	user32\DeleteMenu=tuiui(i)
	user32\DestroyIcon=t(i)
	user32\DestroyMenu=t(i)
	user32\DestroyWindow=t(i)
	user32\DrawIconEx=tiitiiuitui(i)
	user32\DrawMenuBar=t(i)
	user32\DrawTextA=ttitui(i)
	user32\DrawTextExA=ttituit(i)
	user32\DrawTextExW=ttituit(i)
	user32\DrawTextW=ttitui(i)
	user32\EmptyClipboard=(i)
	user32\EnableMenuItem=tuiui(i)
	user32\EnumChildWindows=ttt(i)
	user32\EnumClipboardFormats=ui(ui)
	user32\EnumDisplayDevicesA=tuitui(i)
	user32\EnumDisplayDevicesW=tuitui(i)
	user32\EnumDisplaySettings=tuit(i)
	user32\EnumDisplaySettingsA=tuit(i)
	user32\EnumDisplaySettingsW=tuit(i)
	user32\EnumPropsExA=ttt(i)
	user32\EnumPropsExW=ttt(i)
	user32\EnumWindows=tt(i)
	user32\FillRect=ttt(i)
	user32\FindWindowA=tt(t)
	user32\FindWindowExA=tttt(t)
	user32\FindWindowExW=tttt(t)
	user32\FindWindowW=tt(t)
	user32\GetActiveWindow=(t)
	user32\GetAncestor=tui(t)
	user32\GetCaretBlinkTime=(ui)
	user32\GetCaretPos=t(i)
	user32\GetClassLongA=ti(ut)
	user32\GetClassLongW=ti(ut)
	user32\GetClassName=tti(i)
	user32\GetClassNameA=tti(i)
	user32\GetClassNameW=tti(i)
	user32\GetClientRect=tt(i)
	user32\GetClipboardData=ui(t)
	user32\GetClipboardFormatNameA=uiti(i)
	user32\GetClipboardFormatNameW=uiti(i)
	user32\GetClipboardOwner=(t)
	user32\GetClipboardSequenceNumber=(ui)
	user32\GetClipCursor=t(i)
	user32\GetCursor=(t)
	user32\GetCursorInfo=t(i)
	user32\GetCursorPos=t(i)
	user32\GetDC=t(t)
	user32\GetDCEx=ttui(t)
	user32\GetDlgCtrlID=t(i)
	user32\GetDoubleClickTime=(ui)
	user32\GetFocus=(t)
	user32\GetForegroundWindow=(t)
	user32\GetGUIThreadInfo=uit(i)
	user32\GetIconInfo=tt(i)
	user32\GetKeyboardState=t(i)
	user32\GetKeyNameTextA=iti(i)
	user32\GetKeyNameTextW=iti(i)
	user32\GetLastActivePopup=t(t)
	user32\GetMenu=t(t)
	user32\GetMenuBarInfo=tiit(i)
	user32\GetMenuItemCount=t(i)
	user32\GetMenuItemID=ti(ui)
	user32\GetMenuItemInfoA=tuiit(i)
	user32\GetMenuItemInfoW=tuiit(i)
	user32\GetMenuItemRect=ttuit(i)
	user32\GetMenuState=tuiui(ui)
	user32\GetMenuStringA=tuitiui(i)
	user32\GetMenuStringW=tuitiui(i)
	user32\GetOpenClipboardWindow=(t)
	user32\GetParent=t(t)
	user32\GetPropA=tt(t)
	user32\GetPropW=tt(t)
	user32\GetScrollPos=ti(i)
	user32\GetShellWindow=(t)
	user32\GetSubMenu=ti(t)
	user32\GetSysColor=i(ui)
	user32\GetSystemMenu=ti(t)
	user32\GetSystemMetrics=i(i)
	user32\GetWindow=tui(t)
	user32\GetWindowDC=t(t)
	user32\GetWindowInfo=tt(i)
	user32\GetWindowLongA=ti(t)
	user32\GetWindowLongW=ti(t)
	user32\GetWindowRect=tt(i)
	user32\GetWindowRgnBox=tt(i)
	user32\GetWindowText=tti(i)
	user32\GetWindowTextA=tti(i)
	user32\GetWindowTextLength=t(i)
	user32\GetWindowTextLengthA=t(i)
	user32\GetWindowTextLengthW=t(i)
	user32\GetWindowTextW=tti(i)
	user32\GetWindowThreadProcessId=tt(ui)
	user32\HideCaret=t(i)
	user32\InsertMenuA=tuiuiutt(i)
	user32\InsertMenuW=tuiuiutt(i)
	user32\IntersectRect=ttt(i)
	user32\InvalidateRect=tti(i)
	user32\IsCharAlphaA=c(i)
	user32\IsCharAlphaW=uh(i)
	user32\IsChild=tt(i)
	user32\IsClipboardFormatAvailable=ui(i)
	user32\IsRectEmpty\t(i)
	user32\IsWindow=t(i)
	user32\IsWindowUnicode=t(i)
	user32\IsWindowVisible=t(i)
	user32\LoadCursorA=tt(t)
	user32\LoadCursorFromFileA=t(t)
	user32\LoadCursorFromFileW=t(t)
	user32\LoadCursorW=tt(t)
	user32\LoadIconA=tt(t)
	user32\LoadIconW=tt(t)
	user32\LoadImageA=ttuiiiui(t)
	user32\LoadImageW=ttuiiiui(t)
	user32\LoadStringA=tuiti(i)
	user32\LoadStringW=tuiti(i)
	user32\LockWorkStation=(i)
	user32\MapWindowPoints=tttui(i)
	user32\MessageBoxA=tttui(i)
	user32\MessageBoxW=tttui(i)
	user32\ModifyMenuA=tuiuiutt(i)
	user32\ModifyMenuW=tuiuiutt(i)
	user32\OpenClipboard=t(i)
	user32\PaintDesktop=t(i)
	user32\PostMessageA=tuiutt(i)
	user32\PostMessageW=tuiutt(i)
	user32\PrintWindow=ttui(i)
	user32\PrivateExtractIconsA=tiiittuiui(ui)
	user32\PrivateExtractIconsW=tiiittuiui(ui)
	user32\RedrawWindow=tttui(i)
	user32\RegisterClassA=t(uh)
	user32\RegisterClassExA=t(uh)
	user32\RegisterClassExW=t(uh)
	user32\RegisterClassW=t(uh)
	user32\RegisterClipboardFormatA=t(ui)
	user32\RegisterClipboardFormatW=t(ui)
	user32\RegisterPowerSettingNotification=ttui(t)
	user32\RegisterWindowMessageA=t(ui)
	user32\RegisterWindowMessageW=t(ui)
	user32\ReleaseDC=tt(i)
	user32\RemoveMenu=tuiui(i)
	user32\ScreenToClient=tt(i)
	user32\SendMessageA=tuiutt(t)
	user32\SendMessageW=tuiutt(t)
	user32\SetCaretBlinkTime=ui(i)
	user32\SetClassLongA=tii(ut)
	user32\SetClassLongW=tii(ut)
	user32\SetClipboardData=uit(t)
	user32\SetCursor=t(t)
	user32\SetCursorPos=ii(i)
	user32\SetForegroundWindow=t(i)
	user32\SetKeyboardState=t(i)
	user32\SetMenu=tt(i)
	user32\SetMenuInfo=tt(i)
	user32\SetMenuItemBitmaps=tuiuitt(i)
	user32\SetMenuItemInfoA=tuiit(i)
	user32\SetMenuItemInfoW=tuiit(i)
	user32\SetParent=tt(t)
	user32\SetProp=ttt(i)
	user32\SetPropA=ttt(i)
	user32\SetPropW=ttt(i)
	user32\SetRect=tiiii(i)
	user32\SetSysColors=itt(i)
	user32\SetSystemCursor=tui(i)
	user32\SetWindowLongA=tit(t)
	user32\SetWindowLongW=tit(t)
	user32\SetWindowPos=ttiiiiui(i)
	user32\SetWindowsHookExA=ittui(t)
	user32\SetWindowsHookExW=ittui(t)
	user32\SetWindowText=tt(i)
	user32\SetWindowTextA=tt(i)
	user32\SetWindowTextW=tt(i)
	user32\SetWinEventHook=uiuittuiuiui(t)
	user32\ShowCaret=t(i)
	user32\ShowWindow=ti(i)
	user32\SystemParametersInfoA=uiuitui(i)
	user32\SystemParametersInfoW=uiuitui(i)
	user32\TrackPopupMenu=tuiiiitt(i)
	user32\TrackPopupMenuEx=tuiiitt(i)
	user32\TranslateAccelerator=ttt(i)
	user32\TranslateAcceleratorA=ttt(i)
	user32\TranslateAcceleratorW=ttt(i)
	user32\UnhookWinEvent=t(i)
	user32\UnregisterPowerSettingNotification=t(i)
	user32\UpdateLayeredWindow=ttttttuitui(i)
	user32\WindowFromPoint=ui6(t)
	uxtheme\GetCurrentThemeName=tititi(i)
	uxtheme\SetWindowTheme=ttt(i)
	uxtheme\SetWindowThemeAttribute=titui(i)
	version\GetFileVersionInfoA=tuiuit(i)
	version\GetFileVersionInfoSizeA=tt(ui)
	version\GetFileVersionInfoSizeW=tt(ui)
	version\GetFileVersionInfoW=tuiuit(i)
	version\VerQueryValueA=tttt(i)
	version\VerQueryValueW=tttt(i)
	winhttp\WinHttpTimeToSystemTime=tt(i)
	wininet\FtpCreateDirectoryA=tt(i)
	wininet\FtpCreateDirectoryW=tt(i)
	wininet\FtpDeleteFileA=tt(i)
	wininet\FtpDeleteFileW=tt(i)
	wininet\FtpFindFirstFileA=tttuiut(t)
	wininet\FtpFindFirstFileW=tttuiut(t)
	wininet\FtpGetCurrentDirectoryA=ttt(i)
	wininet\FtpGetCurrentDirectoryW=ttt(i)
	wininet\FtpGetFileA=tttiuiuiut(i)
	wininet\FtpGetFileSize=tt(ui)
	wininet\FtpGetFileW=tttiuiuiut(i)
	wininet\FtpOpenFileA=ttuiuiut(t)
	wininet\FtpOpenFileW=ttuiuiut(t)
	wininet\FtpPutFileA=tttuiut(i)
	wininet\FtpPutFileW=tttuiut(i)
	wininet\FtpRemoveDirectoryA=tt(i)
	wininet\FtpRemoveDirectoryW=tt(i)
	wininet\FtpRenameFileA=ttt(i)
	wininet\FtpRenameFileW=ttt(i)
	wininet\FtpSetCurrentDirectoryA=tt(i)
	wininet\FtpSetCurrentDirectoryW=tt(i)
	wininet\InternetCloseHandle=t(i)
	wininet\InternetConnectA=ttuhttuiuiut(t)
	wininet\InternetConnectW=ttuhttuiuiut(t)
	wininet\InternetFindNextFileA=tt(i)
	wininet\InternetFindNextFileW=tt(i)
	wininet\InternetGetLastResponseInfoA=ttt(i)
	wininet\InternetGetLastResponseInfoW=ttt(i)
	wininet\InternetOpenA=tuittui(t)
	wininet\InternetOpenUrlA=tttuiuiut(t)
	wininet\InternetOpenUrlW=tttuiuiut(t)
	wininet\InternetOpenW=tuittui(t)
	wininet\InternetQueryDataAvailable=ttuiut(i)
	wininet\InternetReadFile=ttuit(i)
	wininet\InternetSetStatusCallback=tt(t)
	wininet\InternetSetStatusCallbackA=tt(t)
	wininet\InternetSetStatusCallbackW=tt(t)
	wininet\InternetWriteFile=ttuit(i)
	winmm\PlaySound=ttui(i)
	winmm\PlaySoundA=ttui(i)
	winmm\PlaySoundW=ttui(i)
	winmm\timeBeginPeriod=ui(ui)
	winmm\timeEndPeriod=ui(ui)
	winmm\timeGetDevCaps=tui(ui)
	ws2_32\htons=uh(uh)
	ws2_32\WSACleanup=(i)
	ws2_32\WSAStartup=uht(i)
	)

	vListDllFunc3 = ;continuation section
	(LTrim
	atl\AtlAxAttachControl=ttt(i)
	atl\AtlAxCreateControl=tttt(i)
	atl\AtlAxGetControl=tt(i)
	atl\AtlAxGetHost=tt(i)
	atl\AtlAxWinInit=(i)
	dwmapi\DwmGetWindowAttribute=tuitui(i)
	dwmapi\DwmIsCompositionEnabled=t(i)
	getuname\GetUName=uht(i)
	imagehlp\ImageDirectoryEntryToData=tucuht(t)
	imagehlp\ImageRvaToVa=ttuit(t)
	imagehlp\MapAndLoad=tttii(i)
	imagehlp\UnMapAndLoad=t(i)
	magnification\MagInitialize=(i)
	magnification\MagSetWindowTransform=tt(i)
	magnification\MagUninitialize=(i)
	msvcrt\_strrev=t(et)
	msvcrt\_wcsrev=t(et)
	msvcrt\atan2=dd(ed)
	msvcrt\atof=t(ed)
	msvcrt\memcmp=ttut(ei)
	msvcrt\memcpy=ttut(ei)
	msvcrt\wcsstr=tt(et)
	ntdll\NtQueryInformationProcess=tituit(i)
	ntdll\NtQuerySystemInformation=ituit(i)
	ntdll\NtReadVirtualMemory=tttutt(i)
	ntdll\NtWow64QueryInformationProcess64=tituit(i)
	ntdll\NtWow64ReadVirtualMemory64=ti6tuit(i)
	ntdll\RtlCompareMemory=ttut(ut)
	ntdll\RtlComputeCrc32=uiti(ui)
	ntdll\RtlFillMemory=tutuc(i)
	ntdll\RtlInitUnicodeString=tt(i)
	ntdll\ZwClose=t(i)
	ntdll\ZwCreateFile=tuitttuiuiuiuitui(i)
	powrprof\PowerApplySettingChanges=tt(ui)
	powrprof\PowerDuplicateScheme=ttt(ui)
	powrprof\PowerGetActiveScheme=tt(ui)
	powrprof\PowerReadACValueIndex=ttttt(ui)
	powrprof\PowerReadDCValueIndex=ttttt(ui)
	powrprof\PowerReadFriendlyName=tttttt(ui)
	powrprof\PowerReadValueIncrement=tttt(ui)
	powrprof\PowerReadValueMax=tttt(ui)
	powrprof\PowerReadValueMin=tttt(ui)
	powrprof\PowerSetActiveScheme=tt(ui)
	powrprof\PowerWriteACValueIndex=ttttui(ui)
	powrprof\PowerWriteDCValueIndex=ttttui(ui)
	powrprof\SetSuspendState=ucucuc(uc)
	propsys\PSGetNameFromPropertyKey=tt(i)
	propsys\PSGetPropertyDescriptionByName=ttt(i)
	propsys\PSGetPropertyKeyFromName=tt(i)
	psapi\EnumProcesses=tuit(i)
	psapi\GetMappedFileNameW=tttui(ui)
	psapi\GetModuleBaseNameW=tttui(ui)
	psapi\GetModuleFileNameExA=tttui(ui)
	psapi\GetModuleFileNameExW=tttui(ui)
	psapi\GetProcessImageFileNameW=ttui(ui)
	)
	;original unmodified Long functions
	;user32\GetClassLongA=ti(ui)
	;user32\GetClassLongW=ti(ui)
	;user32\GetWindowLongA=ti(i)
	;user32\GetWindowLongW=ti(i)
	;user32\SetClassLongA=tii(ui)
	;user32\SetClassLongW=tii(ui)
	;user32\SetWindowLongA=tii(i)
	;user32\SetWindowLongW=tii(i)
	;vListDllFunc := "dummy\dummy=t(t)"
	;. "`n" "dummyA\dummyA=t(t)"
	;. "`n" "dummyW\dummyW=t(t)"
	;dll list - end
	return vListDllFunc1 "`n" vListDllFunc2 "`n" vListDllFunc3
}

;==================================================
@Notus: Cheers, no problem.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 116 guests