Setting the Cursor Image

The cursor is the small image that shows the location of the mouse or other pointing device. Many applications change the cursor image to give feedback to the user. Although it is not required, it adds a nice bit of polish to your application.

Windows provides a set of standard cursor images, called system cursors. These include the arrow, the hand, the I-beam, the hourglass (which is now a spinning circle), and others. This section describes how to use the system cursors. For more advanced tasks, such as creating custom cursors, see Cursors.

You can associate a cursor with a window class by setting the hCursor member of the WNDCLASS or WNDCLASSEX structure. Otherwise, the default cursor is the arrow. When the mouse moves over a window, the window receives a WM_SETCURSOR message (unless another window has captured the mouse). At this point, one of the following events occurs:

  • The application sets the cursor and the window procedure returns TRUE.
  • The application does nothing and passes WM_SETCURSOR to DefWindowProc.

To set the cursor, a program does the following:

  1. Calls LoadCursor to load the cursor into memory. This function returns a handle to the cursor.
  2. Calls SetCursor and passes in the cursor handle.

Otherwise, if the application passes WM_SETCURSOR to DefWindowProc, the DefWindowProc function uses the following algorithm to set the cursor image:

  1. If the window has a parent, forward the WM_SETCURSOR message to the parent to handle.
  2. Otherwise, if the window has a class cursor, set the cursor to the class cursor.
  3. If there is no class cursor, set the cursor to the arrow cursor.

The LoadCursor function can load either a custom cursor from a resource, or one of the system cursors. The following example shows how to set the cursor to the predefined system link select cursor.

    LPCTSTR cursor = IDC_HAND;
    hCursor = LoadCursor(NULL, cursor);

If you change the cursor, the cursor image resets on the next mouse move, unless you intercept the WM_SETCURSOR message and set the cursor again. The following code shows how to handle WM_SETCURSOR.

    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT)
            return TRUE;

This code first checks the lower 16 bits of lParam. If LOWORD(lParam) equals HTCLIENT, it means the cursor is over the client area of the window. Otherwise, the cursor is over the nonclient area. Typically, you should only set the cursor for the client area, and let Windows set the cursor for the nonclient area.


User Input: Extended Example