News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

WindowFromPoint argument list/prototype different in MASM and Win32 API

Started by IanScott, February 08, 2013, 08:37:04 AM

Previous topic - Next topic

IanScott

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



qWord

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.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

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

hutch--

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.

MichaelW

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).

Well Microsoft, here's another nice mess you've gotten us into.

jj2007

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

dedndave


IanScott

Thank you one and all. I am very impressed with the depth of knowledge available in this forum.

jj2007

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


dedndave