News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Problems w/DragDetect

Started by NoCforMe, October 04, 2011, 06:08:43 AM

Previous topic - Next topic

NoCforMe

Trying to use DragDetect() to see if the mouse was dragged, there seem to be two problems with MASM32:

  • The function prototype i(in user32.inc) appears to have the wrong # of parameters; the MSDN documentation says two (a window handle and a pointer to a POINT structure), but proto has 3. (Maybe someone thought the function took the X and Y values separately?)
  • When I changed the include file, the linker complained it couldn't find it (external symbol name = _DragDetect@8).
Anyone know anything about this?

NoCforMe

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.

dedndave

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

jj2007

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

ToutEnMasm

Quote
DragDetect PROTO :DWORD ,:POINT
winuser.sdk

dedndave

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

ToutEnMasm

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


dedndave

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

jj2007

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

NoCforMe

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.

dedndave

masm will accept it if the prototype is set up that way
Yves (ToutEnMasm) does not use the include files from the masm32 package

MichaelW

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

eschew obfuscation

NoCforMe

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?

dedndave

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

MichaelW

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.
eschew obfuscation