Your browser doesn't support JavaScript Working with the Mouse - Windows Programming

Working with the Mouse

Windows can handle a mouse with up to 3 buttons and a mouse wheel. Windows generates mouse messages when the user moves the mouse, presses the mouse buttons or scrolls the mouse wheel, within the client and non-client area. The non-client area of a window consists of borders, a title bar, a menu bar, a minimize/maximize button and an exit button. 

Some Common Client Area Mouse Messages

WM_MOUSEMOVE- Generated when the mouse moves over the client area of a window.
WM_LBUTTONDBLCLK – Left mouse button pressed twice within the double-click time.
WM_LBUTTONDOWN- Left mouse button pressed.
WM_LBUTTONUP – Left mouse button released.
WM_RBUTTONDBLCLK – Right mouse button pressed twice within the double-click time
WM_RBUTTONDOWN – Right mouse button pressed.
WM_RBUTTONUP – Right mouse button released.
WM_MBUTTONDBLCLK – Middle mouse button clicked twice within the double-click time.
WM_MBUTTONDOWN – Middle mouse button pressed.
WM_MBUTTONUP – Middle mouse button released.
WM_SETCURSOR – The mouse cursor needs to change.

When an application receives a mouse message, the lParam value contains the cursor’s x, y position. These coordinates are relative to the upper-left corner of the client area.  To retrieve these x and y values, the most common method is to use the GET_X_LPARAM and GET_Y_LPARAM  macros :

xPos = GET_X_LPARAM(lParam); yPos = GET_Y_LPARAM(lParam);

The value of wParam contains information about the state of the mouse and keyboard. It may contain any combination of the following values –

MK_LBUTTON – Posted when the user presses the left mouse button
MK_MBUTTON – Posted when the user presses the middle mouse button
MK_RBUTTON – Posted when the user presses the right mouse button
MK_SHIFT – Posted when the user presses the shift button
MK_CONTROL – Posted when the user presses the control button
MK_XBUTTON1 – Posted when the user releases the first or second X button

Example

The following program demonstrates mouse and keyboard messages by responding to mouse clicks and displaying the relevant status information at the associated mouse click position on the screen.


Some Common Non-Client Area Mouse Messages

WM_NCLBUTTONDOWN – Left mouse button pressed.
WM_NCLBUTTONUP – Left mouse button released.
WM_NCLBUTTONDBLCLK – Left mouse button clicked twice within the double-click time
WM_NCMBUTTONDOWN – Middle mouse button pressed.
WM_NCMBUTTONUP – Middle mouse button released.
WM_NCMBUTTONDBLCLK – Middle mouse button clicked twice within the double-click time
WM_NCRBUTTONDOWN – Right mouse button pressed.
WM_NCRBUTTONUP – Right mouse button released.
WM_NCRBUTTONDBLCLK – Right mouse button clicked twice within the double-click time
WM_NCMOUSEMOVE – Generated when the mouse moved over the non-client area of a window
WM_NCHITTEST – Tests what type of object the cursor is over (border, caption, client area, etc.)

The lParam value contains the screen position information. The x and y coordinates of the cursor are stored using the POINTS structure.  These coordinates are relative to the upper-left corner of the screen. Screen coordinates can be converted to client coordinates using the API function ScreenToClient().

Detecting the Non-Client Area with WM_NCHITTEST 

The WM_NCHITTEST message can be used to test what type of object the cursor is over (border, caption, client area, etc.)  The return value of the DefWindowProc function is used to identify where in the window’s nonclient area the event occurred – 

case WM_NCHITTEST: hittest = DefWindowProc(hwnd, message, wParam, lParam); if(HTCLIENT == hittest) { }

A selection of these return codes is shown in the table below. 

HTCAPTION – The title bar.
HTCLOSE- The close button.
HTGROWBOX – The restore button (same as HTSIZE).
HTHSCROLL -The window’s horizontal scroll bar.
HTMENU – The menu bar.
HTREDUCE – The minimize button.
HTSIZE – The restore button (same as HTGROWBOX).
HTSYSMENU – The system menu box.
HTVSCROLL -The window’s vertical scroll bar.
HTZOOM -The maximize button

Example

The following short program demonstrates non-client area messages by responding to mouse clicks within the non-client area. Clicking in the title bar, the restore button, the close button, the maximise button, the Windows border or the system menu will output a relevant message within the client area. To close the window double-click anywhere within the non-client area


The Mouse Wheel

The WM_MOUSEWHEEL message is sent when the mouse wheel is rotated. The lParam value contains the cursor’s x and y positions. These coordinates are relative to the upper-left corner of the client screen. The high-order wParam value indicates the distance the wheel is rotated in multiples of 120 with a negative value indicating a backward rotation and a positive value indicating a forward rotation. The low order wparam value indicates various virtual key states.

fwKeys = LOWORD(wParam); // key flag
szDelta = (short) HIWORD(wParam); // wheel rotation
xPos = (short) LOWORD(lParam); // horizontal position of pointer
yPos = (short) HIWORD(lParam); // vertical position of pointer

Capturing the Mouse

A window procedure normally receives mouse messages only when the mouse cursor is positioned over the client or non-client area of the window however a program might need to receive mouse messages when the mouse is outside the window. For example, if a mouse button is clicked inside a window but the mouse moves outside the window’s client area before releasing that button, the window will not receive the button-up event. To remedy this problem, windows allows the application to ‘capture’ the mouse and continue to receive mouse messages when a cursor moves outside the application window. Windows will then continue to receive messages until the button is released or the capture is cancelled. The mouse is captured with the API function SetCapture() and released with ReleaseCapture(). These functions are normally executed in the button-down and button-up handlers

Changing the Mouse Icon

The API function SetCursor allows an application to change the mouse cursor. The syntax for this function is

HCURSOR SetCursor(HCURSOR hCursor);

Where hCursor is a handle to the cursor. The cursor can be created by the CreateCursor() function or loaded by the LoadCursor() or LoadImage() function. If this parameter is NULL, the cursor is removed from the screen.
The return value is the handle to the previous cursor or NULL if there was no previous cursor.

Double Clicks

For a window to register a double click, the window must be set up to be notified of a double click event by setting the style member in the Windows class declaration must be set to CS_DBLCICKS –

wndclass.style=CS_DBLCLKS;

The left and right button double-click messages are WM_LBUTTONDBLCLK and WM_RBUTTONDBLCLK. The contents of the lParam and wParam are the same as for a single click. To set the double click interval use the API function SetDoubleClickTime(UINT interval) and to obtain the double click interval use the function GetDoubleClickTime().