mmikeww / AHK-v2-script-converter

AHK v1 -> v2 script converter
https://autohotkey.com/boards/viewtopic.php?f=6&t=25100
The Unlicense
530 stars 41 forks source link

DllCall: .Ptr property required for structs #76

Open hoffor opened 2 years ago

hoffor commented 2 years ago

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

dmtr99 commented 1 year ago

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 commented 1 year ago

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)
Lexikos commented 1 year ago

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.