Home | API | MFC | C++ | C | Previous | Next

Programming Windows API

Working with the Mouse

Windows is capable of handling 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 area and non-client area. The non-client area is the area of a window consisting of borders, title bar, menu bar, minimize/maximize button, and 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 pressed 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.

Display Code
Download Code

Some Common Non-Client Area Mouse Messages

WM_NCLBUTTONDOWN – Left mouse button pressed.
WM_NCLBUTTONUP – Left mouse button released.
WM_NCLBUTTONDBLCLK – Left mouse button pressed a twice within the double-click time
WM_NCMBUTTONDOWN – Middle mouse button pressed.
WM_NCMBUTTONUP – Middle mouse button released.
WM_NCMBUTTONDBLCLK -Middlemouse button pressed a twice within the double-click time
WM_NCRBUTTONDOWN -Right mouse button pressed.
WM_NCRBUTTONUP Right mouse button released.
WM_NCRBUTTONDBLCLK – Right mouse button pressed a 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.)

As is the case with client area messages the lParam value contains the screen position information. This information is however stored using the POINTS structure that contains the x and y coordinates of the cursor.  These coordinates are relative to the upper-left corner of the screen. Screen coordinate 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 returns 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 verticalscroll 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 titlebar, the restore button, the close button, maximise button, the windows border or the system menu will output a relevant message within the client area. To close the windows double click anywhere within the non-client area

Display Code
Download Code

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 position. 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 keys 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, then the windows 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

In order 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 they are 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()


Home | API | MFC | C++ | C | Previous | Next
Creating a Simple Window | Common Elements | Data Types and Character Sets | The Device Context | Graphics Device Interface | Displaying Text | Displaying Graphics | Mapping Modes | Keyboard Input | Working with the Mouse | Menus | Child Windows | ScrollBar Control | The Dialog Box | Windows Message Box | Common Dialog Box | Bitmaps | Common Controls | Creating a Toolbar | Multiple Document Interface | Timers | DLL’s | Creating Custom Controls | Owner Drawn Controls | API Hooking and DLL Injection | File Management Functions | String Manipulation | System Information Functions