Hello, I don't have enough time now to check this deeply, but You can handle it in this ugly way.
_Test()
Func _Test()
Global $oHTTP = ObjCreate("Msxml2.ServerXMLHTTP")
Global $tMyObject
Global $oMyObject = __ObjectFromTag("__MyInterface_", "OnReadyStateChange hresult(object)", $tMyObject)
Local $oScript = ObjCreate("ScriptControl")
With $oScript
.Language = "VBScript"
.AddCode('Public Function CallBack:oAutoIt.OnReadyStateChange(oRequest):End Function')
.AddObject('oAutoIt', $oMyObject)
.AddObject('oRequest', $oHTTP)
EndWith
With $oHTTP
.Open("GET", "https://www.autohotkey.com/download/1.1/version.txt", True)
.onreadystatechange = $oScript.Eval('GetRef("CallBack")')
.Send()
EndWith
ConsoleWrite("$oHTTP.readyState: " & $oHTTP.readyState & @CRLF)
While $oHTTP.ReadyState <> 4
Sleep(100)
WEnd
Exit
EndFunc ;==>_Test
Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj)
Local $tStruct = DllStructCreate("ptr", $pObj)
DllStructSetData($tStruct, 1, $pSelf)
Return 0 ; $S_OK
EndFunc ;==>__MyInterface_QueryInterface
Func __MyInterface_AddRef($pSelf)
Return 1
EndFunc ;==>__MyInterface_AddRef
Func __MyInterface_Release($pSelf)
Return 1
EndFunc ;==>__MyInterface_Release
Func __MyInterface_OnReadyStateChange($pSelf, $oRequest)
If Not IsObj($oRequest) Then Return ConsoleWrite("Error $oRequest" & @CRLF)
If $oRequest.ReadyState <> 4 Then Return 0
If $oRequest.Status = 200 Then
MsgBox(0, "", "Latest AutoHotkey version: " & $oRequest.responseText)
Else
Exit MsgBox(0, "Error", "Status: " & $oRequest.Status)
EndIf
Return 0 ; $S_OK
EndFunc ;==>__MyInterface_OnReadyStateChange
Func __ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default
If $bIsUnknown = Default Then $bIsUnknown = True
Local $sInterface = $tagInterface ; copy interface description
Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _
"AddRef dword();" & _
"Release dword();"
; Adding IUnknown methods
If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface
; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention
Local $aMethods = StringSplit(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), @LF, 3)
Local $iUbound = UBound($aMethods)
Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback
; Allocation
$tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props
If @error Then Return SetError(1, 0, 0)
For $i = 0 To $iUbound - 1
$aSplit = StringSplit($aMethods[$i], "|", 2)
If UBound($aSplit) <> 2 Then ReDim $aSplit[2]
$sNamePart = $aSplit[0]
; Replace COM types by matching dllcallback types
$sTagPart = StringReplace(StringReplace(StringReplace(StringReplace($aSplit[1], "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr")
$sMethod = $sFunctionPrefix & $sNamePart
$aTagPart = StringSplit($sTagPart, ";", 2)
$sRet = $aTagPart[0]
$sParams = StringReplace($sTagPart, $sRet, "", 1)
$sParams = "ptr" & $sParams
$hCallback = DllCallbackRegister($sMethod, $sRet, $sParams)
DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer
DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle
Next
DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1
DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods
DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers
Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object
EndFunc ;==>__ObjectFromTag
Func __DeleteObjectFromTag(ByRef $tInterface)
For $i = 1 To DllStructGetData($tInterface, "Size")
DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i))
Next
$tInterface = 0
EndFunc ;==>__DeleteObjectFromTag
Saludos