Author Topic: Drawing mouse coordinates  (Read 2103 times)

Moskacz

  • Guest
Drawing mouse coordinates
« on: February 03, 2013, 10:54:25 AM »
Hi,

Im new to MASM. I want to build small program that will be showing mouse position. I know there is GetCursorPosition API function. But i have problem in drawing coordinates on screen. I have a frame and I want two strings in that frame  - "X cord: " and "Y cord: ". Which function i should use to draw double (point.x and point.y) on a screen?

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #1 on: February 03, 2013, 11:00:36 AM »
you don't have to "get" the cursor position
the top window that has the cursor under it will recieve WM_MOUSEMOVE messages (when in client area)
lParam then holds X and Y mouse position

http://msdn.microsoft.com/en-us/library/windows/desktop/ms645616%28v=vs.85%29.aspx

for setting a pixel, you can use SetPixel
not the fastest way, but it will get you started

http://msdn.microsoft.com/en-us/library/windows/desktop/dd145078%28v=vs.85%29.aspx

you may also want to use GetDC to get the window DC

http://msdn.microsoft.com/en-us/library/windows/desktop/dd144871%28v=vs.85%29.aspx

jj2007

  • Member
  • *****
  • Posts: 3434
    • MasmBasic
Re: Drawing mouse coordinates
« Reply #2 on: February 03, 2013, 06:26:24 PM »
Which function i should use to draw double (point.x and point.y) on a screen?

WM_MOUSEMOVE handler plus a borderless static control should do the job. Post your current code, and we'll help you.

Welcome to the forum :icon14:

Gunther

  • Member
  • *****
  • Posts: 2842
  • Forgive your enemies, but never forget their names
Re: Drawing mouse coordinates
« Reply #3 on: February 03, 2013, 09:48:37 PM »
Hi Moskacz,

welcome to the forum.

Gunther
Get your facts first, and then you can distort them.

Moskacz

  • Guest
Re: Drawing mouse coordinates
« Reply #4 on: February 03, 2013, 11:25:44 PM »
Hi again :)

My code:

Code: [Select]
.386

.MODEL FLAT, STDCALL

OPTION CASEMAP:NONE

INCLUDE    \masm32\include\windows.inc
INCLUDE    \masm32\include\user32.inc
INCLUDE    \masm32\include\kernel32.inc
INCLUDE    \masm32\include\gdi32.inc
INCLUDELIB \masm32\lib\user32.lib
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDELIB \masm32\lib\gdi32.lib

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD

;zainicjowane dane

.DATA

ClassName DB "SimpleWinClass",0       ;nazwa naszej klasy okna
AppName   DB "Program pokazujacy obsluge myszki w MASM",0  ;tytuł naszego okna
OurText1 DB "Wspolrzedna X:", 0
OurText2 DB "Wspolrzedna Y:", 0
Position POINT<>
Position2 POINT<>
MouseClick1 db 0
MouseClick2 db 0
LeftButtonText DB "Left_Button", 0
RightButtonText DB "Right_Buton",0

;niezainicjowane dane

.DATA?

hInstance   HINSTANCE ?               ;uchwyt egzemplarza naszego programu
CommandLine LPSTR ?                   ;wskazanie wiersza poleceń

;tutaj rozpoczyna się nasz kod

.CODE

start:
    INVOKE GetModuleHandle, NULL     ;pobieramy uchwyt programu
    mov    hInstance, eax            ;pod Win32 hmodule==hinstance
    INVOKE GetCommandLine            ;pobierz wiersz polecenia. Nie musisz wywoływać
    mov    CommandLine, eax          ;tej funkcji, jeśli twój program nie przetwarza
                                     ;wiersza polecenia
    INVOKE WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT ;główna funkcja
    INVOKE ExitProcess, eax          ;kończymy program. Kod wyjścia jest zwracany
                                     ;w eax z WinMain.

WinMain PROC hInst:     HINSTANCE,\
             hPrevInst: HINSTANCE,\
             CmdLine:   LPSTR,\
             CmdShow:   DWORD

LOCAL wc:   WNDCLASSEX               ;na stosie tworzymy zmienne lokalne
LOCAL msg:  MSG
LOCAL hwnd: HWND
                                     ;wypełniamy pola struktury wc
    mov    wc.cbSize, SIZEOF WNDCLASSEX
    mov    wc.style, CS_HREDRAW or CS_VREDRAW
    mov    wc.lpfnWndProc, OFFSET WndProc
    mov    wc.cbClsExtra, NULL
    mov    wc.cbWndExtra, NULL
    push   hInstance
    pop    wc.hInstance
    mov    wc.hbrBackground, COLOR_WINDOW+1
    mov    wc.lpszMenuName, NULL
    mov    wc.lpszClassName, OFFSET ClassName
    INVOKE LoadIcon, NULL, IDI_APPLICATION
    mov    wc.hIcon, eax
    mov    wc.hIconSm, eax
    INVOKE LoadCursor,NULL, IDC_ARROW
    mov    wc.hCursor, eax
    INVOKE RegisterClassEx, ADDR wc   ;rejestrujemy naszą klasę okna
    INVOKE CreateWindowEx, NULL,\
                           ADDR ClassName,\
                           ADDR AppName,\
                           WS_OVERLAPPEDWINDOW,\
                           CW_USEDEFAULT,\
                           CW_USEDEFAULT,\
                           600,\
                           600,\
                           NULL,\
                           NULL,\
                           hInst,\
                           NULL
    mov    hwnd, eax
    INVOKE ShowWindow, hwnd, CmdShow  ;wyświetlamy nasze okno na pulpicie
    INVOKE UpdateWindow, hwnd         ;odświeżamy obszar roboczy

    .WHILE TRUE                       ;wchodzimy w pętle wiadomości
        INVOKE GetMessage, ADDR msg, NULL, 0, 0
        .BREAK .IF (!eax)
        INVOKE TranslateMessage, ADDR msg             
        INVOKE DispatchMessage, ADDR msg
    .ENDW

    mov eax, msg.wParam              ;kod powrotu zwracamy w eax
    ret

WinMain ENDP

WndProc PROC hWnd:   HWND, uMsg:   UINT, wParam: WPARAM, lParam: LPARAM

LOCAL hdc: HDC
LOCAL ps: PAINTSTRUCT
LOCAL rect: RECT

    .IF uMsg==WM_DESTROY
        INVOKE PostQuitMessage, NULL
    .ELSEIF uMsg==WM_LBUTTONDOWN
        mov    eax, lParam
        and    eax, 0ffffh
        mov    Position.x, eax
        mov    eax, lParam
        shr    eax, 16
        mov    Position.y, eax
        mov    MouseClick1, TRUE
        mov    MouseClick2, FALSE
        INVOKE InvalidateRect, hWnd, NULL, TRUE
       
    .ELSEIF uMsg==WM_RBUTTONDOWN
        mov    eax, lParam
        and    eax, 0ffffh
        mov    Position2.x, eax
        mov    eax, lParam
        shr    eax, 16
        mov    Position2.y, eax
        mov    MouseClick2, TRUE
        mov    MouseClick1, FALSE
        INVOKE InvalidateRect, hWnd, NULL, TRUE

    .ELSEIF uMsg==WM_PAINT
        INVOKE BeginPaint, hWnd, ADDR ps
        mov    hdc, eax
       
        .IF MouseClick1
            INVOKE lstrlen, ADDR AppName
            INVOKE TextOut, hdc, Position.x, Position.y,\
                            ADDR LeftButtonText, eax
                           
        .ENDIF
       
        .IF MouseClick2
            INVOKE lstrlen, ADDR AppName
            INVOKE TextOut, hdc, Position2.x, Position2.y,\
                            ADDR RightButtonText, eax
           
        .ENDIF
       
        INVOKE EndPaint, hWnd, ADDR ps
    .ELSE
        INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .ENDIF


    xor eax, eax
    ret

WndProc ENDP


END start

Now, if i click left or right button my program will draw text that starts in clicked position. But I still want to draw coordinates of mouse cursor on a screen, and i don't know how. I know how to get x and y cord , but how draw this on a screen?

PS. I know my code may be stupid or something, but I started learning this yesterday.

Greetings!

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #5 on: February 03, 2013, 11:30:07 PM »
first, you have to convert the binary values into ascii decimal strings
the masm32 package has functions and macros for that
(see str$ macro in masm32\help\hlhelp.chm)

but, to display the text, use TextOut, ExtTextOut, DrawText, or DrawTextEx

personally, i would find it easier to create a status bar and display the position, there
you create the status bar
convert the value to ascii decimal
then use SendMessage to tell the status bar what string to display

Moskacz

  • Guest
Re: Drawing mouse coordinates
« Reply #6 on: February 03, 2013, 11:51:06 PM »
How to create statusbar?

Farabi

  • Member
  • ****
  • Posts: 733
  • Neuroscience Fans
Re: Drawing mouse coordinates
« Reply #7 on: February 03, 2013, 11:56:04 PM »
How to create statusbar?

Use CreateWindowEx. I think it had a statusbar component.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #8 on: February 04, 2013, 12:15:16 AM »
yes - i prefer CreateWindowEx - there is also CreateStatusWindow

but, to use CreateWindowEx, use the pre-defined class string
Code: [Select]
szStatusClass db 'msctls_statusbar32',0
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760726%28v=vs.85%29.aspx

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #9 on: February 04, 2013, 12:22:03 AM »
here is a simple example of a status bar with mouse position
i used CreateStatusWindow, because it is simpler for beginners

Moskacz

  • Guest
Re: Drawing mouse coordinates
« Reply #10 on: February 04, 2013, 01:25:14 AM »
OK, i know how to create status bar but I still don't understand how did you convert long to dword.

I have position: POINT<>, so position.x and position.y hold my coords and i must convert these numbers to dword.

You told me to use str$ macro.
Here is code of this macro:

sstr$ MACRO number
        LOCAL buffer
        .data?
          buffer TCHAR 40 dup (?)
          align 4
        .code
        IFNDEF __UNICODE__
          invoke crt__ltoa,number,ADDR buffer,10
        ELSE
          invoke crt__ltow,number,ADDR buffer,10
        ENDIF
        EXITM <eax>
      ENDM

But if I have local variable tmp: DWORD i can't use this macro in this way - mov tmp, sstr$(position.x) [invalid symbol type in expression sstr$()].
What is the correct way to use this macro?

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #11 on: February 04, 2013, 01:32:57 AM »
yes - sorry about that
in my little example program i wrote my own routine to do the conversion
the drawback of that is - i don't think my little routine will handle negative numbers
the client coordinates should never be negative, but you never know   :P

but - for you, it may be easier to use one of the masm32 functions or macros
in the case of signed values, Hutch uses crt__ltoa from the MSVCRT library
you can do the same

Code: [Select]
invoke crt__ltoa,number,ADDR buffer,10number is the value to be converted (could be in a register like ECX or EDX)
addr buffer is the address of the string buffer
10 is the radix or base

the macro creates the string and returns the address
that may not be convenient, in this case

Moskacz

  • Guest
Re: Drawing mouse coordinates
« Reply #12 on: February 04, 2013, 02:05:13 AM »
Now I want to convert coordinates of point when I click somewhere in client area:

Code: [Select]
.ELSEIF uMsg==WM_RBUTTONDOWN
        mov    eax, lParam
        and    eax, 0ffffh
        mov    Position2.x, eax
        mov    eax, lParam
        shr    eax, 16
        mov    Position2.y, eax
        mov    MouseClick2, TRUE
        mov    MouseClick1, FALSE
        INVOKE InvalidateRect, hWnd, NULL, TRUE
        invoke crt__ltoa,Position2.x,tmpX,10

tmpX is a local variable :
LOCAL tmpX: DWORD

But it's not working, with line
Code: [Select]
invoke crt__ltoa,Position2.x,tmpX,10i got window with message 'program.exe has stopped working' (when i click right button)

What's wrong? :/

dedndave

  • Member
  • *****
  • Posts: 6792
  • Still using Abacus 2.0
Re: Drawing mouse coordinates
« Reply #13 on: February 04, 2013, 02:15:52 AM »
yes - it crashed because it wants the address of a string buffer
unless "tmpX" contains an address, you may get an access violation

for signed values, the buffer should be at least 12 bytes long
do not pass the contents - pass the address

Moskacz

  • Guest
Re: Drawing mouse coordinates
« Reply #14 on: February 04, 2013, 02:39:42 AM »
Thanks!

Stupid mistake, now everything is working!  :t