The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: NoCforMe on October 04, 2011, 06:08:43 AM

Title: Problems w/DragDetect
Post by: NoCforMe on October 04, 2011, 06:08:43 AM
Trying to use DragDetect() to see if the mouse was dragged, there seem to be two problems with MASM32:

Anyone know anything about this?
Title: Re: Problems w/DragDetect
Post by: NoCforMe on October 04, 2011, 06:19:25 AM
OK, figured it out.

The C function does take 2 arguments, not 3. Thing is, the 2nd one is a POINT structure which has 2 DWORDs (X and Y). No way to push that on the stack as one parm.

So the assembly-language call is:
INVOKE DragDetect, handle, pt.x, pt.y

The include file is correct after all.
Title: Re: Problems w/DragDetect
Post by: dedndave on October 04, 2011, 10:41:05 AM
you can look these functions up on MSDN for reference...
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646256%28v=vs.85%29.aspx

all you have to do is "translate" from C to ASM
BOOL WINAPI DragDetect(
  __in  HWND hwnd,
  __in  POINT pt
);


        INVOKE  DragDetect,hwnd,pt

they don't normally show POINT parameters that way - it would usually be a pointer to a POINT structure
in this case, it should be
        INVOKE  DragDetect,hwnd,x,y
Title: Re: Problems w/DragDetect
Post by: jj2007 on October 04, 2011, 11:29:01 AM
You can do a 1:1 translation like this:
include \masm32\include\masm32rt.inc

MyDragDetect PROTO TheHandle:HWND, ThePoints:POINT

.code
MyPoints POINT <456, 789>
start: invoke MyDragDetect, 123, MyPoints
inkey "ok"
exit

MyDragDetect proc TheHandle:HWND, ThePoints:POINT
  print "Px="
  print str$(ThePoints.x), 13, 10
  print "Py="
  print str$(ThePoints.y), 13, 10
  ret
MyDragDetect endp
end start


It works, but you can only pass a POINT structure itself, not individual members such as in invoke MyDragDetect, 123, 456, 789
Title: Re: Problems w/DragDetect
Post by: ToutEnMasm on October 04, 2011, 12:33:20 PM
Quote
DragDetect PROTO :DWORD ,:POINT
winuser.sdk
Title: Re: Problems w/DragDetect
Post by: dedndave on October 04, 2011, 05:51:03 PM
yah - that's how it should be   :P
but then you wouldn't be able to use 2 dword parms - you'd always have to combine them
Title: Re: Problems w/DragDetect
Post by: ToutEnMasm on October 04, 2011, 05:58:24 PM
Quote
but then you wouldn't be able to use 2 dword parms - you'd always have to combine them
:naughty:
.data
pt POINT <>
.code
      mov pt.x,35 
      mov pt.y,15
     invoke  DragDetect,hwnd,pt        ;masm accept

Title: Re: Problems w/DragDetect
Post by: dedndave on October 04, 2011, 06:01:09 PM
no fun if you happen to have X and Y in register
you can do it by pushing the regs and hwnd, then call

it's more fun to...
        INVOKE DragDetect,hWin,ecx,edx

:P

actually, i like this function for that, but it is the only one that i have seen
normally, i create the POINT struct on the stack, then pass the pointer in ESP
this saves a PUSH and 2 POP's - lol
Title: Re: Problems w/DragDetect
Post by: jj2007 on October 04, 2011, 07:00:49 PM
Your version works but mine works and is older and shorter :bg
Quote from: jj2007 on October 04, 2011, 11:29:01 AM
MyPoints POINT <456, 789>
start: invoke MyDragDetect, 123, MyPoints

Quote from: ToutEnMasm on October 04, 2011, 05:58:24 PM
.data
pt POINT <>
.code
      mov pt.x,35 
      mov pt.y,15
     invoke  DragDetect,hwnd,pt        ;masm accept
Title: Re: Problems w/DragDetect
Post by: NoCforMe on October 04, 2011, 07:49:49 PM
Quote from: ToutEnMasm on October 04, 2011, 05:58:24 PM
Quote
but then you wouldn't be able to use 2 dword parms - you'd always have to combine them
:naughty:
.data
pt POINT <>
.code
      mov pt.x,35 
      mov pt.y,15
     invoke  DragDetect,hwnd,pt        ;masm accept



'MASM accept"? I don't think so. Are you sure?
First problem: too few arguments (the prototype calls for 3).
Second problem: argument type mismatch (it's looking for a DWORD, but you're passing a structure of 2 DWORDs).

Are you using the standard MASM32 include files? Which version of MASM are you using?

I've already determined that


INVOKE DragDetect, handle, pt.X, pt.Y


works correctly, and is apparently what the MASM32 coder intended.
Title: Re: Problems w/DragDetect
Post by: dedndave on October 04, 2011, 07:55:08 PM
masm will accept it if the prototype is set up that way
Yves (ToutEnMasm) does not use the include files from the masm32 package
Title: Re: Problems w/DragDetect
Post by: MichaelW on October 04, 2011, 08:01:51 PM
The prototype is a problem, but passing a structure on the stack is no problem.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================

printf MACRO format:REQ, args:VARARG
    IFNB <args>
        invoke crt_printf, cfm$(format), args
    ELSE
        invoke crt_printf, cfm$(format)
    ENDIF
    EXITM <>
ENDM

;==============================================================================
    .data
        rect RECT <0,1,2,3>
    .code
;==============================================================================

testrc proc rc:RECT
    printf( "%d\t%d\t%d\t%d\n\n", rc.left, rc.top, rc.right, rc.bottom )
    ret
testrc endp

;==============================================================================
start:
;==============================================================================

    invoke testrc, rect

    inkey "Press any key to exit..."
    exit
   
;==============================================================================
end start

Title: Re: Problems w/DragDetect
Post by: NoCforMe on October 04, 2011, 08:04:47 PM
But it looks like you're passing members (OK, "fields" if you prefer) of the structure, not the whole structure itself.

Regarding Yves' coding, what does his prototype for DragDetect() look like? Is the 2nd parameter a quad word?
Title: Re: Problems w/DragDetect
Post by: dedndave on October 04, 2011, 08:06:58 PM
well - it is a POINT - not exactly the same as a QWORD, but it's the same size
POINT is a structure definition
in masm, that makes it a type, for all practical purposes
Title: Re: Problems w/DragDetect
Post by: MichaelW on October 04, 2011, 08:13:35 PM
Invoke is passing the whole structure, in "stack-size" chunks and in the correct memory order. Invoke does basically the same thing when passing a REAL8, for example.
Title: Re: Problems w/DragDetect
Post by: NoCforMe on October 04, 2011, 08:20:39 PM
Yes; here's what happens 'behind the scenes" (I find it very useful to actually look all the assembler-generated stuff, using the /Fl /Sg options). I created a dummy function "xxx" that takes a POINT as its argument:


xxx proto :POINT

invoke xxx, pt
000002D3  FF 75 FC    *     push   dword  ptr ss:[ebp]+0FFFFFFFCh
000002D6  FF 75 F8    *     push   dword  ptr ss:[ebp]+0FFFFFFF8h
000002D9  E8 00000000 E   *     call   xxx


which does exactly what you described.

If you thnk about it, this is just the kind of thing about assembly language that would drive any language purist (like C programmers!) nuts. This seems like the classic ill-defined behavior. Is this even documented anywhere? I haven't seen anything covering this in the MASM manual, f'rinstance.

Anyhow, we know it works, so I guess that's what counts, eh?
Title: Re: Problems w/DragDetect
Post by: jj2007 on October 04, 2011, 08:39:43 PM
Quote from: NoCforMe on October 04, 2011, 08:20:39 PM...the classic ill-defined behavior. Is this even documented anywhere?

Yes, somewhere here in the Forum :bg
Passing a structure is possible but rarely used. As your listing and Olly show, it takes a whopping 12 bytes to pass a global POINT (from my example above):
<ModuleEnt  .  FF35 04104000            push dword ptr [401004]
0040100E    .  FF35 00104000            push dword ptr [401000]


Most of the time you have the x & y points in registers anyway - and two push exx takes only two bytes.