Seventh lesson to handle mouse input messages
In this lesson, we will learn how to handle mouse button messages in our window process function. The sample program demonstrates how to wait for the left button to press the message, we will display a string in the pressed position.
Theory: Like the input keyboard, Windows will capture mouse action and send them to related windows. These activities include left, right-click, move, double click, etc. (translator Note: The new mouse also includes roller messages WM_WHEEL). Windows is not like processing the keyboard input, and all mouse messages are directed to a window with input focus, and any mouse will receive the mouse message, whether or not to enter the focus. In addition, the window will also receive the mouse in a non-client message (WM_NCMOVE), but most of us will ignore it. There are two messages for each button of the mouse: WM_LButtondown, WM_RBUTTONDOWN. There is a WM_MBUTTONDOWN and WM_MBUTTONUP messages for the three-key mouse, which will receive the WM_MOUSEMOVE message when the mouse moves in a window client area. If a window wants to handle WM_LBUTTONDBCLK or WM_RBUTTONDBCLK, then its window class must have a CS_DBLCLKS style, otherwise it will accept a pile of buttons (WM_XBUTTONDOWN or WM_XBUTTONUP) messages. For all messages, the parameter LPARAM that the window process function is incorporated in the position of the mouse, where the bottom is x coordinate, the high position is Y coordinate, which is the value of the upper left corner of the window client area, WPARAM The state of the mouse button is included.
example:
.386
.Model flat, stdcall
Option CaseMAP: NONE
Winmain Proto: DWORD,: DWORD,: DWORD,: DWORD
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 incrudelib /masm32/lib/gdi32.lib
.data classname db "simplewinclass", 0 Appname DB "Our First Window", 0 mouseClick DB 0; 0 = no click Yet
.DATA? HINSTANCE HINSTANCE? COMMANDLINE LPSTR? HitPoint Point <>
. Code Start: Invoke GetModuleHandle, Null Mov Hinstance, Eax Invoke Getcommandline Mov Commandline, Eax Invoke Winmain, Hinstance, Null, CommandLine, SW_SHOWDEFAULT INVOKE EXITPROCESS, EAX
WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD LOCAL wc: WNDCLASSEX LOCAL msg: MSG LOCAL hwnd: HWND 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 hInst 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 invoke CreateWindowEx, NULL, aDDR ClassName, aDDR AppName, / WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, / CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, / HINST, NULL MOV HWND, EAX INVOKE ShowWindow, Hwnd, SW_SHOWNORMAL INVOKE UPDATEWINDOW, HWND .WHILE TRUE INVOKE GETMESSAGE, Addr MSG, NULL, 0, 0.Break .if (! EAX) Invoke DispatchMessage, Addr Msg .Endw Mov EAX, MSG.WParam Ret Winmain EndpWndProc Proc HWnd: HWnd, UMSG: UINT, WPARAM: WPARAM, LPARAM: LPARAM LOCAL HDC : Hdc local ps: Paintstruct
.IF uMsg == WM_DESTROY invoke PostQuitMessage, NULL .ELSEIF uMsg == WM_LBUTTONDOWN mov eax, lParam and eax, 0FFFFh mov hitpoint.x, eax mov eax, lParam shr eax, 16 mov hitpoint.y, eax mov MouseClick, TRUE invoke InvalidateRect , hWnd, NULL, TRUE .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov hdc, eax .IF MouseClick invoke lstrlen, ADDR AppName invoke TextOut, hdc, hitpoint.x, hitpoint.y, ADDR AppName, eax .ENDIF Invoke Endpaint, Hwnd, Addr Ps .lse Invoke DefWindowProc, HWND, UMSG, WPARAM, LPARAM RET WndProc END START analysis:
.ELSEIF uMSG == WM_LButtondown
Mov Eax, LPARAM
And Eax, 0FFFFH
Mov HitPoint.x, EAX
Mov Eax, LPARAM
SHR EAX, 16
Mov HitPoint.y, EAX
MOV Mouseclick, True
Invoke InvalidateRect, HWND, NULL, TRUE
The window process handles the WM_LBUTTONDOWN message. When the message is received, the LParam contains coordinates relative to the upper left corner of the window client area, and we save it, put it in a structural variable (POINT), the structure variable Defined as follows:
Point Struct X DD? Y DD? Point Ends
Then we set the marker MouseClick to True, indicating that at least once the left button on the client area presses the message.
Mov Eax, LParam and Eax, 0FFFFH MOV Hitpoint.x, EAX
Since LPARAM is a 32-bit long number, high, the bottom 16 bits include x, y coordinates, so we do some small processing to save them.
SHR EAX, 16 MOV HitPoint.y, after saving the coordinate we set the flag mouseclick to true, which is used to determine if there is a mouse left mouse button when processing WM_PAINT. Then we call the InvalIDateRect () function forcing Windows to reselect the client area.
. IF Mouseclick Invoke Lstrlen, Addr Appname Invoke Textout, HDC, Hitpoint.x, Hitpoint.y, Addr Appname, Eax .Endif