;~ #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 ;#AutoIt3Wrapper_UseX64 = y #include "..\Direct2D.au3" #include "..\DirectWrite.au3" ;derived from _DWrite_Factory_Create Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc") Func _ErrFunc() ConsoleWrite("COM Error, ScriptLine(" & $oError.ScriptLine & ") : Number 0x" & Hex($oError.Number, 8) & " - " & $oError.WinDescription & @CRLF) EndFunc ;==>_ErrFunc Global $pOldFuncTest _Example() Func _Example() Local $sString = "Hello World" Local $hGui = GUICreate("Direct2D", 800, 300) Local $oFactory = _D2D_Factory_Create() Local $oRender = _D2D_Factory_CreateHwndRenderTarget($oFactory, $hGui) Local $oBrush = _D2D_RenderTarget_CreateSolidColorBrush($oRender, 1, 1, 0) Local $oDW_Factory = _DWrite_Factory_Create() Local $oDW_Format = _DWrite_Factory_CreateTextFormat($oDW_Factory, "Arial", 128) Local $pObj=Ptr($oDW_Factory) Local $pNewFuncTest=DllCallbackGetPtr(DllCallbackRegister( "GetGdiInterop", "long", "ptr*" )), $pTest ;~ Local $pNewFuncTest=DllCallbackGetPtr(DllCallbackRegister( "QueryInterfaceReplacement", "long", "ptr;ptr*" )), $pTest $pOldFuncTest=ReplaceVTableFuncPtr($pObj,(15+3-1)*4,$pNewFuncTest);3 from IUnknown, -1 - first offset iz zero;(15+3-1)*4 ;24 prints 'Caught' For $i=1 To 7 ConsoleWrite($i & "=") ConsoleWrite(ObjName($oDW_Factory,$i) & @CRLF) Next $oDW_Factory.GetGdiInterop($pTest) MsgBox(0,"After test","There should be single 'Caught' at the console") GUISetState() $oRender.BeginDraw() _D2D_RenderTarget_Clear($oRender, 0, 0, 0.3) ;~ _D2D_RenderTarget_DrawText($oRender, $sString, $oDW_Format, 0, 0, 800, 300, $oBrush) $oRender.EndDraw(0, 0) While GUIGetMsg() <> -3 WEnd $oDW_Format = 0 $oDW_Factory = 0 $oBrush = 0 $oRender = 0 $oFactory = 0 GUIDelete($hGui) EndFunc ;==>_Example Func QueryInterfaceReplacement($pSelf, $vParam1, $vParam2) ConsoleWrite("QueryInterface" & @CRLF) ConsoleWrite("Param1:" & $vParam1) DllCallAddress("long",$pOldFuncTest,"ptr",$pSelf,"ptr",$vParam1,"ptr*",$vParam2) Return 0 EndFunc Func GetGdiInterop($pSelf, $oParam1) ConsoleWrite("Caught" & @CRLF) Local $test ;~ $iResult=DllCallAddress("long",$pOldFuncTest,"ptr",$pSelf,"ptr*",$test) ;~ ConsoleWrite("$iResult=" & $iResult & @CRLF) ;~ $oParam1=ObjCreateInterface($pGDIInterOp,$sIID_IDWriteGdiInterop,$tagIDWriteGdiInterop) Return 0 EndFunc ; Copied from "Hooking into the IDispatch interface" by monoceres ; https://www.autoitscript.com/forum/index.php?showtopic=107678 Func ReplaceVTableFuncPtr( $pVTable, $iOffset, $pNewFunc ) Local $pPointer = DllStructGetData( DllStructCreate( "ptr", $pVTable ), 1 ) + $iOffset, $PAGE_EXECUTE_READWRITE = 0x40 Local $pOldFunc = DllStructGetData( DllStructCreate( "ptr", $pPointer ), 1 ) ; Get the original function pointer in VTable Local $aRet = DllCall( "Kernel32.dll", "int", "VirtualProtect", "ptr", $pPointer, "long", @AutoItX64 ? 8 : 4, "dword", $PAGE_EXECUTE_READWRITE, "dword*", 0 ) ; Unprotect memory DllStructSetData( DllStructCreate( "ptr", $pPointer ), 1, $pNewFunc ) ; Replace function pointer in VTable with $pNewFunc function pointer DllCall( "Kernel32.dll", "int", "VirtualProtect", "ptr", $pPointer, "long", @AutoItX64 ? 8 : 4, "dword", $aRet[4], "dword*", 0 ) ; Protect memory Return $pOldFunc ; Return original function pointer EndFunc