News:

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

is there GET_X_LPARAM function in MASM32?

Started by supercoollee, September 21, 2011, 01:47:02 PM

Previous topic - Next topic

supercoollee

i am trying to implement mouse movement control into my program, but can't assemble the code if i use GET_X_LPARAM / GET_Y_LPARAM functions, what can i do?

dedndave

those are c compiler macros   :P

for signed integers....
        movsx   eax,word ptr lParam    ;EAX = X (low word)
        movsx   edx,word ptr lParam+2  ;EDX = Y (high word)


for unsigned integers....
        movzx   eax,word ptr lParam    ;EAX = X (low word)
        movzx   edx,word ptr lParam+2  ;EDX = Y (high word)

MichaelW

As Dave stated, GET_X_LPARAM and GET_Y_LPARAM are macros, not functions. This example replaces them with MASM macros:

;==============================================================================
; Build as console app.
;==============================================================================
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

;==============================================================================

GET_X_LPARAM MACRO lParam:REQ
    IFNDEF _GET_X_LPARAM_rv_
        .data
            _GET_X_LPARAM_rv_ dd 0
        .code
    ENDIF
    mov eax, lParam
    and eax, 0ffffh
    mov _GET_X_LPARAM_rv_, eax
    EXITM <_GET_X_LPARAM_rv_>
ENDM

GET_Y_LPARAM MACRO lParam:REQ
    IFNDEF _GET_Y_LPARAM_rv_
        .data
            _GET_Y_LPARAM_rv_ dd 0
        .code
    ENDIF
    mov eax, lParam
    shr eax, 16
    mov _GET_Y_LPARAM_rv_, eax
    EXITM <_GET_Y_LPARAM_rv_>
ENDM

;==============================================================================
    .data

    .code
;==============================================================================

DialogProc proc hwndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

    SWITCH uMsg

        CASE WM_INITDIALOG

        CASE WM_LBUTTONDOWN

            printf( "%d\t%d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) )

        CASE WM_COMMAND

            SWITCH wParam

                CASE IDCANCEL

                    invoke EndDialog, hwndDlg, NULL

            ENDSW

      CASE WM_CLOSE

        invoke EndDialog, hwndDlg, NULL

    ENDSW

    return 0

DialogProc endp
;==============================================================================
start:
;==============================================================================

    Dialog "Test", \
           "FixedSys", 11, \
            WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
            0, \
            0,0,100,75, \
            1024

    invoke GetModuleHandle, NULL
    CallModalDialog eax, 0, DialogProc, NULL

    exit
;==============================================================================
end start


Edit: I coded the macros to return the coordinates in dedicated memory variables so they can be combined in a single invoke without one overwriting the return value for the other. For individual use the code could simply return the coordinate in a register. Or for situations where their use of EAX is a problem, they could be coded to use only memory variables.




eschew obfuscation

supercoollee

i am trying to rorate a camera with the mouse , code like this:

......................... in mainloop

.elseif umsg == WM_MOUSEMOVE
     movsx   eax,word ptr lParam
     movsx   edx,word ptr lParam+2
    mov mousexpos,eax
    mov mouseypos,edx
    ret

.................. in my doevent code

    mov eax,mousexpos
    test eax,eax
    je campanfinish
    fild word ptr mousexpos
    fmul dword ptr interval
    fmul dword ptr campanrate
    fadd dword ptr camheading
    fstp dword ptr camheading
campanfinish:
    mov eax,mouseypos
    test eax,eax
    je campitchfinish
    fild word ptr mouseypos
    fmul dword ptr interval
    fmul dword ptr campitchrate
    fadd dword ptr campitch
    fstp dword ptr campitch
campitchfinish:
    xor eax,eax
    mov mousexpos,eax
    mov mouseypos,eax
    mov eax,winwidth
    shr eax,1
    mov edx,winheight
    shr edx,1
    invoke SetCursorPos,eax,edx

..................... then run GLfunctions

but the mousexpos & mouseypos seem to be always positive integers, what is wrong?

supercoollee

when i use keyboard control, the program was correct, but now with mouse control, it's wrong.

ToutEnMasm


dedndave

Yves is right
but also, they are screen coordinates - not movement displacements like the old DOS INT 33h stuff   :P
visible screen coordinates are always positive (the upper left corner of the screen is 0,0)
you should use MOVZX instead of MOVSX and re-write the event code accordingly

dedndave

i might add....
here are a few other functions you may find useful

1) GetSystemMetrics - use SM_CXSCREEN and SM_CYSCREEN to get overall screen dimensions
http://msdn.microsoft.com/en-us/library/ms724385%28v=VS.85%29.aspx

2) ScreenToClient - for converting screen coordinates to client coordinates
http://msdn.microsoft.com/en-us/library/dd162952%28v=vs.85%29.aspx

3) ClientToScreen - for converting client coordinates to screen coordinates
http://msdn.microsoft.com/en-us/library/dd183434%28v=VS.85%29.aspx

you may not need that last one

supercoollee

thanks. now the code works. should be like this - substract half the window size:


    movsx eax, word ptr lparam
    movsx edx, word ptr lparam+2
    mov ecx,winwidth
    shr ecx,1
    sub eax,ecx
    mov ecx,winheight
    shr ecx,1
    sub edx,ecx
    mov mousexpos,eax
    mov mouseypos,edx
    ret

dedndave

that code looks fishy   :P

i generally use the stack to create a temporary POINT structure
it's fast, and it makes for small code
        movzx   edx,word ptr lParam+2
        movzx   eax,word ptr lParam
        push    edx
        push    eax
        INVOKE  ScreenToClient,hWnd,esp
        pop     eax                    ;EAX = X client coordinate
        pop     edx                    ;EDX = Y client coordinate


EDIT - oops - forgot the window handle   :bg