The windows API indicates that WindowFromPoint has a single argument, that is a POINT structure. The C++ specification in MSDN is
HWND WINAPI WindowFromPoint(
_In_ POINT Point
);
However, whilst trying to assemble a MASM program an exception was thrown (error A2137: too few arguments to INVOKE) when I coded the call to WindowFromPoint as:- invoke WindowFromPoint, [edx].pt
When I code invoke WindowFromPoint, [edx].pt.x, [edx].pt.y from an example I found it assembles. Further investigation reveals the prototype for WindowFromPoint in user.inc requires two arguments which accounts for the assembly error but doesn't account for the difference to the API specification.
Any ideas as to why these two are different ?
Thanks
MASM has also the capacity to handle the correct declaration using a structure, but the version from the MASM32 SDK is simpler to use (in some cases) and produce the same result.
as qWord says, it is simpler to pass 2 dwords in ASM...
INVOKE WindowFromPoint,x,y
there are a few of these - another is one of the Rect functions, PtInRect, i think
Ian,
HWND WINAPI WindowFromPoint(
_In_ POINT Point
);
The difference occurs because the C prototype is doing something different. The linker data has 2 DWORD values and that is how it is called correctly from MASM, a C compiler translates the 2 item structure into 2 DWORD values.
Using the documented syntax, Invoke passes the structure as two dwords.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
pt POINT <1,2>
.code
;==============================================================================
_WindowFromPoint proc point:POINT
printf("%d\t%d\n", point.x, point.y)
ret
_WindowFromPoint endp
;==============================================================================
start:
;==============================================================================
invoke _WindowFromPoint, pt
inkey
exit
;==============================================================================
end start
invoke _WindowFromPoint, pt
0000001B 4 FF 35 00000004 R * push dword ptr pt+000000004h
00000021 4 FF 35 00000000 R * push dword ptr pt
00000027 3 E8 FFFFFFD4 * call _WindowFromPoint
And the same for PtInRect.
I have not done any exhaustive tests but Invoke seems to pass even relatively large structures (I think I recently tested a BITMAP structure) on the stack correctly, as long as they do not contain BYTE members (I tested this detail only on ML 6.14 and 6.15).
Here is also the reg::reg notation, building on Michael's example:
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
pt POINT <1,2>
pt2 QWORD 1+1000000h*2
.code
;==============================================================================
_WindowFromPoint proc point:POINT
printf("%d\t%d\n", point.x, point.y)
ret
_WindowFromPoint endp
_WindowFromPointQ proc ptq:QWORD
printf("%d\t%d\n", dword ptr ptq, dword ptr ptq[4])
ret
_WindowFromPointQ endp
_WindowFromPoint2 proc pointX:DWORD, pointY:DWORD
printf("%d\t%d\n", pointX, pointY)
ret
_WindowFromPoint2 endp
;==============================================================================
start:
;==============================================================================
invoke _WindowFromPoint, pt ; "correct" API compatible version
invoke _WindowFromPoint2, pt.x, pt.y ; Masm32 style
mov eax, pt.x
mov edx, pt.y
invoke _WindowFromPointQ, edx::eax ; reg::reg notation
inkey
exit
end start
didn't know you could do that, either - lol :t
Thank you one and all. I am very impressed with the depth of knowledge available in this forum.
Thanks, Ian. Hope to see you more often around :icon14:
@Dave: I am a bit surprised that this doesn't work - technically it's easy to implement:
mov eax, pt.x
mov edx, pt.y
invoke _WindowFromPointQ, edx::eax ; reg::reg notation
invoke _WindowFromPointQ, pt.x::pt.y ; dword::dword notation is not possible
in that case, you can pass the structure :P