AHK-v2-script-converter icon indicating copy to clipboard operation
AHK-v2-script-converter copied to clipboard

DllCall: .Ptr property required for structs

Open hoffor opened this issue 2 years ago • 3 comments

pfd is a struct made using Buffer (prev VarSetCapacity) and NumPut

v1: DllCall("SetPixelFormat", "uInt", hwndDC, "uInt", iPixelFormat, "uInt", &pfd)

v2 good: DllCall("SetPixelFormat", "uInt", hwndDC, "uInt", iPixelFormat, "uInt", pfd.Ptr)

your v2: DllCall("SetPixelFormat", "uInt", hwndDC, "uInt", iPixelFormat, "uInt", pfd) Error: Expected a Number but got a Buffer

same result if uInt is instead Ptr

hoffor avatar Aug 13 '22 05:08 hoffor

Is the following assumption correct? DllCall(random, Type := "uInt", Arg) if (Type = "uInt" or Type = "Prt") and Arg starts with & => "uInt", Arg.Ptr

Or shoud we first check how the arg is made ( by VarSetCapacity)?

dmtr99 avatar Mar 22 '23 22:03 dmtr99

The documentation does not seem to follow the logic. Or should .Ptr be added if the type is not "Ptr" and the variable is made by Buffer (prev VarSetCapacity)?

V1:

Run Notepad
WinWait Untitled - Notepad  ; This also sets the "last found window" for use with WinExist() below.
VarSetCapacity(Rect, 16)  ; A RECT is a struct consisting of four 32-bit integers (i.e. 4*4=16).
DllCall("GetWindowRect", "Ptr", WinExist(), "Ptr", &Rect)  ; WinExist() returns an HWND.
MsgBox % "Left " . NumGet(Rect, 0, "Int") . " Top " . NumGet(Rect, 4, "Int")
    . " Right " . NumGet(Rect, 8, "Int") . " Bottom " . NumGet(Rect, 12, "Int")

V2:

Run "Notepad"
WinWait "Untitled - Notepad"  ; This also sets the "last found window" for use with WinExist below.
Rect := Buffer(16)  ; A RECT is a struct consisting of four 32-bit integers (i.e. 4*4=16).
DllCall("GetWindowRect", "Ptr", WinExist(), "Ptr", Rect)  ; WinExist returns an HWND.
L := NumGet(Rect, 0, "Int"), T := NumGet(Rect, 4, "Int")
R := NumGet(Rect, 8, "Int"), B := NumGet(Rect, 12, "Int")
MsgBox Format("Left {1} Top {2} Right {3} Bottom {4}", L, T, R, B)

dmtr99 avatar Mar 25 '23 15:03 dmtr99

v2 good: DllCall("SetPixelFormat", "uInt", hwndDC, "uInt", iPixelFormat, "uInt", pfd.Ptr)

Not good!

You should not pass a pointer value to a "uInt" parameter. Pointers are 64-bit on x64. "uInt" is ostensibly always 32-bit.

It will work anyway because DllCall doesn't bother to truncate the value (since any function taking a 32-bit parameter should completely ignore the upper 32 bits in a 64-bit value), but it is still better to use the proper type.

Lexikos avatar Jul 22 '23 02:07 Lexikos