The MASM Forum

General => The Campus => Topic started by: IanScott on February 08, 2013, 08:37:04 AM

Title: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: IanScott on February 08, 2013, 08:37:04 AM
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


Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: qWord on February 08, 2013, 08:47:56 AM
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.
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: dedndave on February 08, 2013, 09:27:47 AM
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
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: hutch-- on February 08, 2013, 11:57:33 AM
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.
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: MichaelW on February 08, 2013, 02:32:35 PM
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).

Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: jj2007 on February 09, 2013, 10:50:18 AM
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
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: dedndave on February 09, 2013, 11:54:35 AM
didn't know you could do that, either - lol   :t
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: IanScott on February 11, 2013, 08:05:25 AM
Thank you one and all. I am very impressed with the depth of knowledge available in this forum.
Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: jj2007 on February 11, 2013, 09:16:06 AM
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

Title: Re: WindowFromPoint argument list/prototype different in MASM and Win32 API
Post by: dedndave on February 11, 2013, 09:28:49 AM
in that case, you can pass the structure   :P