Sehr interessant!
Alternativ hätte ich diese Version, welche nur mehr eine globale Variable verwendet und etwas schlanker ist:
Code
#include-once
Global $__t_VSYNC
Func _VSync_Startup()
If IsDllStruct($__t_VSYNC) Then Return True
$__t_VSYNC = DllStructCreate("struct; handle Dll; hwnd Gui; ptr Fac; ptr Tar; endstruct; ")
$__t_VSYNC.Dll = DllOpen('d2d1.dll') ; Direct2D Dll
If @error Or Not $__t_VSYNC.Dll Then Return SetError(1, 1, False)
$__t_VSYNC.Gui = GUICreate("VSync", 1, 1, 0, 0, 0x80000000) ; GUI mit der Größe 1x1px oben links im Bildschirm, unsichtbar
Local $tIID_ID2D1Factory = DllStructCreate("struct; ulong Data1; ushort Data2; ushort Data3; byte Data4[8]; endstruct; ")
DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", "{06152247-6f50-465a-9245-118bfd3b6007}", "struct*", $tIID_ID2D1Factory)
Local $aResult = DllCall($__t_VSYNC.Dll, "int", "D2D1CreateFactory", "uint", 0, "struct*", $tIID_ID2D1Factory, "uint*", 0, "ptr*", 0)
If @error Or $aResult[0] Or Not $aResult[4] Then
_VSync_Shutdown()
Return SetError(1, 2, False)
EndIf
$__t_VSYNC.Fac = $aResult[4]
Local $pHwndRenderTarget, $tRenderTargetProperties = DllStructCreate("struct; uint Type; uint PixelFormat; uint AlphaMode; float DpiX; float DpiY; uint Usage; uint MinLevel; endstruct; ")
Local $tHWNDRenderTargetProperties = DllStructCreate("struct; hwnd Hwnd; uint Width; uint Height; uint PresentOptions; endstruct; ")
$tHWNDRenderTargetProperties.Hwnd = $__t_VSYNC.Gui
$tHWNDRenderTargetProperties.Width = 1
$tHWNDRenderTargetProperties.Height = 1
Local $tObj = DllStructCreate("struct; ptr VTBL; endstruct; ", $__t_VSYNC.Fac)
Local $tCall = DllStructCreate("struct; ptr[15]; endstruct; ", $tObj.VTBL)
$aResult = DllCallAddress("int", DllStructGetData($tCall, 1, 15), "struct*", $__t_VSYNC.Fac, "struct*", $tRenderTargetProperties, "struct*", $tHWNDRenderTargetProperties, "ptr*", 0)
If @error Or $aResult[0] Or Not $aResult[4] Then
_VSync_Shutdown()
Return SetError(1, 3, False)
EndIf
$__t_VSYNC.Tar = $aResult[4]
Return $__t_VSYNC
EndFunc ;==>_VSync_Startup
Func _VSync_Shutdown()
If Not IsDllStruct($__t_VSYNC) Then Return SetError(1, 1, False)
Local $tObj, $tCall, $aResult
If $__t_VSYNC.Tar Then
$tObj = DllStructCreate("struct; ptr VTBL; endstruct; ", $__t_VSYNC.Tar)
$tCall = DllStructCreate("struct; ptr[3]; endstruct; ", $tObj.VTBL)
$aResult = DllCallAddress("int", DllStructGetData($tCall, 1, 3), "struct*", $__t_VSYNC.Tar) ;Release
EndIf
If $__t_VSYNC.Fac Then
$tObj = DllStructCreate("struct; ptr VTBL; endstruct; ", $__t_VSYNC.Fac)
$tCall = DllStructCreate("struct; ptr[3]; endstruct; ", $tObj.VTBL)
$aResult = DllCallAddress("int", DllStructGetData($tCall, 1, 3), "struct*", $__t_VSYNC.Fac) ;Release
EndIf
GUIDelete($__t_VSYNC.Gui)
DllClose($__t_VSYNC.Dll)
$__t_VSYNC = Null
Return True
EndFunc ;==>_VSync_Shutdown
Func _VSync_Wait()
If Not IsDllStruct($__t_VSYNC) Then Return SetError(1, 1, False)
Local $tObj = DllStructCreate("struct; ptr VTBL; endstruct; ", $__t_VSYNC.Tar)
Local $tCall = DllStructCreate("struct; ptr[50]; endstruct; ", $tObj.VTBL)
DllCallAddress("int", DllStructGetData($tCall, 1, 49), "struct*", $__t_VSYNC.Tar) ;BeginDraw
DllCallAddress("int", DllStructGetData($tCall, 1, 50), "struct*", $__t_VSYNC.Tar, "uint64*", 0, "uint64*", 0) ;EndDraw
Return True
EndFunc ;==>_VSync_Wait
Alles anzeigen
Um ganz auf globale Variablen zu verzichten, könnte man $__t_VSYNC auch als Return bzw. Byref übergeben...