Example 1: a POINT struct
(adapted from mouse scroll wheel script)
MouseGetPos, x, y hwnd:=DllCall("WindowFromPoint", int, x, int, y) ; works in 32 bit but not in 64 bit
According to MSDN, WindowFromPoint() takes a POINT struct, defined as two 32 bit values (LONG). Since "int" is 32 bits in both x86 and x64, it would seem the argument sizes shouldn't need to be changed for x64. However, in AHK_L x64 (latest version 1.1.05.06), only the x argument has any effect, and as a result it returns hwnds only for windows along the top of the screen.
Exhibt 2: a VARIANT struct
(adapted from the original ACC.AHK lib)
DllCall("LoadLibrary",str,"oleacc", ptr) VarSetCapacity(Point, 8, 0) DllCall("GetCursorPos", ptr, &Point) DllCall("oleacc\AccessibleObjectFromPoint", "int64", NumGet(Point, 0, "int64"), ptrp, pAccessible, ptr, &varChild) ; get vtable for IAccessible vtAccessible := NumGet(pAccessible+0, "ptr") ; call get_accName() through the vtable hr := DllCall(NumGet(vtAccessible+0, 10*A_PtrSize, "ptr"), ptr, pAccessible,"int64", 3, "int64", 0,"int64", 0 ptrp, pvariant) ; variant's type is VT_I4 = 3 ; variant's value is CHILDID_SELF = 0 ; get_accName returns the following hresult error with 64 bit ahk hr_facility := (0x07FF0000 & hr) >>16 ; shows facility = 7 "win32" hr_code := 0x0000ffff & hr ; code 1780 "RPC_X_NULL_REF_POINTER"
In Example 1, a workaround for the POINT struct was possible by passing a single "int64" parameter instead. However, this couldn't be done for Example 2, because a VARIANT struct (24 bytes in x64) is larger than the largest argument size available for DllCall().
In Example 2: The original ACC.AHK library, which was written for x86, faked the VARIANT struct by passing two "int64"s in the function call. The same technique doesn't seem to work under AHK_L 64 bit -- as shown above, a third "int64" was added to adjust the size of the variant parameter up to 24 bytes. Further notes:
a. the other vtable functions which don't take a VARIANT as a direct parameter work fine.
b. invoking that same function via the IDispatch works fine, because IDispatch takes variants as pointers. [/list]
I'm not sure if this might have something to do with the different calling convention used in x64 (eg stdcall in x86 versus fastcall in x64). There were a few other areas in the Windows API I came across where structs are passed directly as arguments. Is there any way to specify or verify the calling convention used by DllCall()? Or is there any way to affect how parameters get pushed onto the call stack or registers, for example whether small variables get zero-extended, etc? It would be nice to get all those great scripts upgraded to 64 bits.
Thanks a bunch