Edit

Share via


Using Cursors

This section discusses the following topics.

Creating a Cursor

The following example creates two cursor handles: one for the standard hourglass cursor and one for a custom cursor included as a resource in the application's resource-definition file.

HINSTANCE hinst;            // handle to current instance 
HCURSOR hCurs1, hCurs2;     // cursor handles 
 
// Create a standard hourglass cursor. 
 
hCurs1 = LoadCursor(NULL, IDC_WAIT); 
 
// Create a custom cursor based on a resource. 
 
hCurs2 = LoadCursor(hinst, MAKEINTRESOURCE(240)); 

Applications should implement custom cursors as resources and use LoadCursor, LoadCursorFromFile, or LoadImage rather than create the cursor at run time. Using cursor resources avoids device dependence, simplifies localization, and enables applications to share cursor designs.

The following example uses the CreateCursor function to create a custom monochrome cursor at run time. The example is included here to illustrate how the system interprets cursor masks.

HINSTANCE hinst;            // handle to current instance  
HCURSOR hCurs1, hCurs2;     // cursor handles 
 
HCURSOR hCurs3;             // cursor handle 
 
// Yin-shaped cursor AND mask (32x32x1bpp)
 BYTE ANDmaskCursor[] =
{
    0xFF, 0xFC, 0x3F, 0xFF,   // ##############----##############
    0xFF, 0xC0, 0x1F, 0xFF,   // ##########---------#############
    0xFF, 0x00, 0x3F, 0xFF,   // ########----------##############
    0xFE, 0x00, 0xFF, 0xFF,   // #######---------################
    0xF8, 0x01, 0xFF, 0xFF,   // #####----------#################
    0xF0, 0x03, 0xFF, 0xFF,   // ####----------##################
    0xF0, 0x03, 0xFF, 0xFF,   // ####----------##################
    0xE0, 0x07, 0xFF, 0xFF,   // ###----------###################
    0xC0, 0x07, 0xFF, 0xFF,   // ##-----------###################
    0xC0, 0x0F, 0xFF, 0xFF,   // ##----------####################
    0x80, 0x0F, 0xFF, 0xFF,   // #-----------####################
    0x80, 0x0F, 0xFF, 0xFF,   // #-----------####################
    0x80, 0x07, 0xFF, 0xFF,   // #------------###################
    0x00, 0x07, 0xFF, 0xFF,   // -------------###################
    0x00, 0x03, 0xFF, 0xFF,   // --------------##################
    0x00, 0x00, 0xFF, 0xFF,   // ----------------################
    0x00, 0x00, 0x7F, 0xFF,   // -----------------###############
    0x00, 0x00, 0x1F, 0xFF,   // -------------------#############
    0x00, 0x00, 0x0F, 0xFF,   // --------------------############
    0x80, 0x00, 0x0F, 0xFF,   // #-------------------############
    0x80, 0x00, 0x07, 0xFF,   // #--------------------###########
    0x80, 0x00, 0x07, 0xFF,   // #--------------------###########
    0xC0, 0x00, 0x07, 0xFF,   // ##-------------------###########
    0xC0, 0x00, 0x0F, 0xFF,   // ##------------------############
    0xE0, 0x00, 0x0F, 0xFF,   // ###-----------------############
    0xF0, 0x00, 0x1F, 0xFF,   // ####---------------#############
    0xF0, 0x00, 0x1F, 0xFF,   // ####---------------#############
    0xF8, 0x00, 0x3F, 0xFF,   // #####-------------##############
    0xFE, 0x00, 0x7F, 0xFF,   // #######----------###############
    0xFF, 0x00, 0xFF, 0xFF,   // ########--------################
    0xFF, 0xC3, 0xFF, 0xFF,   // ##########----##################
    0xFF, 0xFF, 0xFF, 0xFF    // ################################
};
 
// Yin-shaped cursor XOR mask (32x32x1bpp)
BYTE XORmaskCursor[] =
{
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x03, 0xC0, 0x00,   // --------------####--------------
    0x00, 0x3F, 0x00, 0x00,   // ----------######----------------
    0x00, 0xFE, 0x00, 0x00,   // --------#######-----------------
    0x03, 0xFC, 0x00, 0x00,   // ------########------------------
    0x07, 0xF8, 0x00, 0x00,   // -----########-------------------
    0x07, 0xF8, 0x00, 0x00,   // -----########-------------------
    0x0F, 0xF0, 0x00, 0x00,   // ----########--------------------
    0x1F, 0xF0, 0x00, 0x00,   // ---#########--------------------
    0x1F, 0xE0, 0x00, 0x00,   // ---########---------------------
    0x3F, 0xE0, 0x00, 0x00,   // --#########---------------------
    0x3F, 0xE0, 0x00, 0x00,   // --#########---------------------
    0x3F, 0xF0, 0x00, 0x00,   // --##########--------------------
    0x7F, 0xF0, 0x00, 0x00,   // -###########--------------------
    0x7F, 0xF8, 0x00, 0x00,   // -############-------------------
    0x7F, 0xFC, 0x00, 0x00,   // -#############------------------
    0x7F, 0xFF, 0x00, 0x00,   // -###############----------------
    0x7F, 0xFF, 0x80, 0x00,   // -################---------------
    0x7F, 0xFF, 0xE0, 0x00,   // -##################-------------
    0x3F, 0xFF, 0xE0, 0x00,   // --#################-------------
    0x3F, 0xC7, 0xF0, 0x00,   // --########----######------------
    0x3F, 0x83, 0xF0, 0x00,   // --#######------#####------------
    0x1F, 0x83, 0xF0, 0x00,   // ---######------#####------------
    0x1F, 0x83, 0xE0, 0x00,   // ---######------####-------------
    0x0F, 0xC7, 0xE0, 0x00,   // ----######----#####-------------
    0x07, 0xFF, 0xC0, 0x00,   // -----#############--------------
    0x07, 0xFF, 0xC0, 0x00,   // -----#############--------------
    0x01, 0xFF, 0x80, 0x00,   // -------##########---------------
    0x00, 0xFF, 0x00, 0x00,   // --------########----------------
    0x00, 0x3C, 0x00, 0x00,   // ----------####------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00    // --------------------------------
};
 
// Create a custom cursor at run time. 
 
hCurs3 = CreateCursor( hinst,   // app. instance 
             19,                // horizontal position of hot spot 
             2,                 // vertical position of hot spot 
             32,                // cursor width 
             32,                // cursor height 
             ANDmaskCursor,     // AND mask 
             XORmaskCursor );   // XOR mask 

To create the cursor, CreateCursor applies the following truth table to the AND and XOR masks.

AND mask XOR mask Display
0 0 Black
0 1 White
1 0 Screen
1 1 Reverse screen

For more information, see Bitmaps.

Creating an Alpha Blended Cursor

Follow these steps to create an alpha blended cursor or icon at run time:

  • Complete a BITMAPV5HEADER structure, as in the code example following these steps, to define a 32 bits per pixel (BPP) alpha blended DIB.
  • Call the CreateDIBSection function to create a DIB section based on the BITMAPV5HEADER structure that you completed.
  • Use the bitmap and alpha information that you want for your alpha blended cursor or icon to complete the DIB section.
  • Complete an ICONINFO structure.
  • Place an empty monochrome bitmap in the hbmMask field, and then place the alpha blended DIB section in the hbmColor field.
  • Call the CreateIconIndirect function to create the alpha blended cursor or icon.

The following code demonstrates how to create an alpha blended cursor. You can use the same code to create an alpha blended icon by changing the fIcon member of the ICONINFO structure to TRUE:

HCURSOR CreateAlphaCursor(void)
{
    HDC hMemDC;
    DWORD dwWidth, dwHeight;
    BITMAPV5HEADER bi;
    HBITMAP hBitmap, hOldBitmap;
    void *lpBits;
    DWORD x,y;
    HCURSOR hAlphaCursor = NULL;

    dwWidth  = 32;  // width of cursor
    dwHeight = 32;  // height of cursor

    ZeroMemory(&bi,sizeof(BITMAPV5HEADER));
    bi.bV5Size           = sizeof(BITMAPV5HEADER);
    bi.bV5Width           = dwWidth;
    bi.bV5Height          = dwHeight;
    bi.bV5Planes = 1;
    bi.bV5BitCount = 32;
    bi.bV5Compression = BI_BITFIELDS;
    // The following mask specification specifies a supported 32 BPP
    // alpha format for Windows XP.
    bi.bV5RedMask   =  0x00FF0000;
    bi.bV5GreenMask =  0x0000FF00;
    bi.bV5BlueMask  =  0x000000FF;
    bi.bV5AlphaMask =  0xFF000000; 

    HDC hdc;
    hdc = GetDC(NULL);

    // Create the DIB section with an alpha channel.
    hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, 
        (void **)&lpBits, NULL, (DWORD)0);

    hMemDC = CreateCompatibleDC(hdc);
    ReleaseDC(NULL,hdc);

    // Draw something on the DIB section.
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    PatBlt(hMemDC,0,0,dwWidth,dwHeight,WHITENESS);
    SetTextColor(hMemDC,RGB(0,0,0));
    SetBkMode(hMemDC,TRANSPARENT);
    TextOut(hMemDC,0,9,"rgba",4);
    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);

    // Create an empty mask bitmap.
    HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL);

    // Set the alpha values for each pixel in the cursor so that
    // the complete cursor is semi-transparent.
    DWORD *lpdwPixel;
    lpdwPixel = (DWORD *)lpBits;
    for (x=0;x<dwWidth;x++)
       for (y=0;y<dwHeight;y++)
       {
           // Clear the alpha bits
           *lpdwPixel &= 0x00FFFFFF;
           // Set the alpha bits to 0x9F (semi-transparent)
           *lpdwPixel |= 0x9F000000;
           lpdwPixel++;
       }

    ICONINFO ii;
    ii.fIcon = FALSE;  // Change fIcon to TRUE to create an alpha icon
    ii.xHotspot = 0;
    ii.yHotspot = 0;
    ii.hbmMask = hMonoBitmap;
    ii.hbmColor = hBitmap;

    // Create the alpha cursor with the alpha DIB section.
    hAlphaCursor = CreateIconIndirect(&ii);

    DeleteObject(hBitmap);          
    DeleteObject(hMonoBitmap); 

    return hAlphaCursor;
}

Before closing, you must use the DestroyCursor function to destroy any cursors you created with CreateCursor or CreateIconIndirect. It is not necessary to destroy cursors created by other functions.

Getting a Cursor size

See Getting the Icon size.

Displaying a Cursor

The system automatically displays the class cursor (the cursor associated with the window to which the cursor is pointing). You can assign a class cursor while registering a window class. The following example illustrates this by assigning a cursor handle to the hCursor member of the WNDCLASS structure identified by the wc parameter.

WNDCLASS  wc; 
 
// Fill the window class structure with parameters that 
// describe the main window. 
 
wc.style = NULL;                        // class style(s) 
wc.lpfnWndProc = (WNDPROC) MainWndProc; // window procedure 
wc.cbClsExtra = 0;           // no per-class extra data 
wc.cbWndExtra = 0;           // no per-window extra data 
wc.hInstance = hinst;        // application that owns the class 
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);     // class icon 
wc.hCursor = LoadCursor(hinst, MAKEINTRESOURCE(230)); // class cursor 
wc.hbrBackground = GetStockObject(WHITE_BRUSH); // class background 
wc.lpszMenuName =  "GenericMenu";               // class menu 
wc.lpszClassName = "GenericWClass"              // class name 
 
// Register the window class. 
 
return RegisterClass(&wc); 

When the window class is registered, the cursor identified by 230 in the application's resource-definition file is the default cursor for all windows based on the class.

Your application can change the design of the cursor by using the SetCursor function and specifying a different cursor handle. However, when the cursor moves, the system redraws the class cursor at the new location. To prevent the class cursor from being redrawn, you must process the WM_SETCURSOR message. Each time the cursor moves and mouse input is not captured, the system sends this message to the window in which the cursor is moving.

You can specify different cursors for different conditions while processing WM_SETCURSOR. For example, the following example shows how to display the cursor whenever the cursor moves over the icon of a minimized application.

case WM_SETCURSOR: 
 
    // If the window is minimized, draw the hCurs3 cursor. 
    // If the window is not minimized, draw the default 
    // cursor (class cursor). 
 
    if (IsIconic(hwnd)) 
    { 
        SetCursor(hCurs3); 
        break; 
    } 

When the window is not minimized, the system displays the class cursor.

You can replace a class cursor by using the SetClassLong function. This function changes the default window settings for all windows of a specified class. The following example replaces the existing class cursor with the hCurs2 cursor.

// Change the cursor for window class represented by hwnd. 
 
SetClassLongPtr(hwnd,    // window handle 
    GCLP_HCURSOR,        // change cursor 
    (LONG_PTR) hCurs2);  // new cursor 

For more information, see Window Classes and Mouse Input.

Confining a Cursor

The following example confines the cursor to the application's window and then restores the cursor to its previous window. The example uses the GetClipCursor function to record the area in which the cursor can move and the ClipCursor function to confine and restore the cursor.

RECT rcClip;           // new area for ClipCursor
RECT rcOldClip;        // previous area for ClipCursor
 
// Record the area in which the cursor can move. 
 
GetClipCursor(&rcOldClip); 
 
// Get the dimensions of the application's window. 
 
GetWindowRect(hwnd, &rcClip); 
 
// Confine the cursor to the application's window. 
 
ClipCursor(&rcClip); 
 
   // 
   // Process input from the confined cursor. 
   // 
 
// Restore the cursor to its previous area. 
 
ClipCursor(&rcOldClip); 

Because there is only one cursor at a time available in the system, an application that confines the cursor must restore the cursor before relinquishing control to another window.

Using Cursor Functions to Create a Mousetrap

The following example uses the SetCursorPos, GetCursorPos, CreateCursor, LoadCursor, and SetCursor functions to create a simple mousetrap. It also uses cursor and timer functions to monitor the cursor's position every 10 seconds. If the cursor position has not changed in the last 10 seconds and the application's main window is minimized, the application changes the cursor and moves it to the mousetrap icon.

An example for a similar mousetrap is included in Icons. It uses the LoadCursor and LoadIcon functions instead of the more device-dependent CreateCursor and CreateIcon functions.

HICON hIcon1;               // icon handles 
POINT ptOld;                // previous cursor location 
HCURSOR hCurs1;             // cursor handle 
 
 
// The following cursor masks are defined in a code 
// example that appears earlier in this section. 
 
// Yin-shaped cursor AND and XOR masks 
 
BYTE ANDmaskCursor[] = ... 
BYTE XORmaskCursor[] = ... 
 
// Yang-shaped icon AND mask (32x32x1bpp)
BYTE ANDmaskIcon[] =
{
    0xFF, 0xFF, 0xFF, 0xFF,   // ################################
    0xFF, 0xFF, 0xC3, 0xFF,   // ##################----##########
    0xFF, 0xFF, 0x00, 0xFF,   // ################--------########
    0xFF, 0xFE, 0x00, 0x7F,   // ###############----------#######
    0xFF, 0xFC, 0x00, 0x1F,   // ##############-------------#####
    0xFF, 0xF8, 0x00, 0x0F,   // #############---------------####
    0xFF, 0xF8, 0x00, 0x0F,   // #############---------------####
    0xFF, 0xF0, 0x00, 0x07,   // ############-----------------###
    0xFF, 0xF0, 0x00, 0x03,   // ############------------------##
    0xFF, 0xE0, 0x00, 0x03,   // ###########-------------------##
    0xFF, 0xE0, 0x00, 0x01,   // ###########--------------------#
    0xFF, 0xE0, 0x00, 0x01,   // ###########--------------------#
    0xFF, 0xF0, 0x00, 0x01,   // ############-------------------#
    0xFF, 0xF0, 0x00, 0x00,   // ############--------------------
    0xFF, 0xF8, 0x00, 0x00,   // #############-------------------
    0xFF, 0xFC, 0x00, 0x00,   // ##############------------------
    0xFF, 0xFF, 0x00, 0x00,   // ################----------------
    0xFF, 0xFF, 0x80, 0x00,   // #################---------------
    0xFF, 0xFF, 0xE0, 0x00,   // ###################-------------
    0xFF, 0xFF, 0xE0, 0x01,   // ###################------------#
    0xFF, 0xFF, 0xF0, 0x01,   // ####################-----------#
    0xFF, 0xFF, 0xF0, 0x01,   // ####################-----------#
    0xFF, 0xFF, 0xF0, 0x03,   // ####################----------##
    0xFF, 0xFF, 0xE0, 0x03,   // ###################-----------##
    0xFF, 0xFF, 0xE0, 0x07,   // ###################----------###
    0xFF, 0xFF, 0xC0, 0x0F,   // ##################----------####
    0xFF, 0xFF, 0xC0, 0x0F,   // ##################----------####
    0xFF, 0xFF, 0x80, 0x1F,   // #################----------#####
    0xFF, 0xFF, 0x00, 0x7F,   // ################---------#######
    0xFF, 0xFC, 0x00, 0xFF,   // ##############----------########
    0xFF, 0xF8, 0x03, 0xFF,   // #############---------##########
    0xFF, 0xFC, 0x3F, 0xFF    // ##############----##############
};
 
// Yang-shaped icon XOR mask (32x32x1bpp)
BYTE XORmaskIcon[] =
{
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x38, 0x00,   // ------------------###-----------
    0x00, 0x00, 0x7C, 0x00,   // -----------------#####----------
    0x00, 0x00, 0x7C, 0x00,   // -----------------#####----------
    0x00, 0x00, 0x7C, 0x00,   // -----------------#####----------
    0x00, 0x00, 0x38, 0x00,   // ------------------###-----------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00,   // --------------------------------
    0x00, 0x00, 0x00, 0x00    // --------------------------------
};

hIcon1 = CreateIcon(hinst, // handle to app. instance 
             32,           // icon width 
             32,           // icon height 
             1,            // number of XOR planes 
             1,            // number of bits per pixel 
             ANDmaskIcon,  // AND mask 
             XORmaskIcon); // XOR mask 
 
hCurs1 = CreateCursor(hinst, // handle to app. instance
             19,             // horizontal position of hot spot 
             2,              // vertical position of hot spot 
             32,             // cursor width 
             32,             // cursor height 
             ANDmaskCursor,  // AND mask 
             XORmaskCursor); // XOR mask 
 
// Fill in the window class structure. 
 
WNDCLASS  wc; 
 
wc.hIcon = hIcon1;                        // class icon 
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // class cursor 
 
//
// Register the window class and perform 
// other application initialization. 
//
 
// Set a timer for the mousetrap. 
 
GetCursorPos(&ptOld); 
 
SetTimer(hwnd, IDT_CURSOR, 10000, (TIMERPROC) NULL); 
 
LONG APIENTRY MainWndProc( 
    HWND hwnd,          // window handle 
    UINT message,       // type of message 
    UINT wParam,        // additional information 
    LONG lParam)        // additional information 
{ 
 
    HDC hdc;            // handle to device context 
    POINT pt;           // current cursor location 
    RECT rc;            // minimized window location 
 
    switch (message) 
    { 
        //
        // Process other messages. 
        // 
        case WM_TIMER: 
        // If the window is minimized, compare the 
        // current cursor position with the one 10 
        // seconds before. If the cursor position has 
        // not changed, move the cursor to the icon. 
 
            if (IsIconic(hwnd)) 
            { 
                GetCursorPos(&pt); 
 
                if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) 
                { 
                    GetWindowRect(hwnd, &rc); 
                    SetCursorPos(rc.left + 20, rc.top + 4); 
 
                    // Note that the additional constants 
                    // (20 and 4) are application-specific 
                    // values to align the yin-shaped cursor 
                    // and the yang-shaped icon. 
 
                } 
                else 
                { 
                    ptOld.x = pt.x; 
                    ptOld.y = pt.y; 
                } 
            } 
 
            return 0; 
 
        case WM_SETCURSOR: 
        // If the window is minimized, draw hCurs1. 
        // If the window is not minimized, draw the 
        // default cursor (class cursor). 
 
            if (IsIconic(hwnd)) 
            { 
                SetCursor(hCurs1); 
                break; 
            } 
 
        case WM_DESTROY: 
        // Destroy timer. 
 
            KillTimer(hwnd, IDT_CURSOR); 
 
            PostQuitMessage(0); 
            break; 
    } 
} 

Using the Keyboard to Move the Cursor

Because the system does not require a mouse, an application should be able to simulate mouse actions with the keyboard. The following example shows how to achieve this by using the GetCursorPos and SetCursorPos functions and by processing input from the arrow keys.

HCURSOR hCurs1, hCurs2;    // cursor handles 
 
POINT pt;                  // cursor location  
RECT rc;                   // client area coordinates 
static int repeat = 1;     // repeat key counter 
 
// 
// Other declarations and initialization. 
// 
 
switch (message) 
{ 
// 
// Process other messages. 
// 
 
    case WM_KEYDOWN: 
 
        if (wParam != VK_LEFT && wParam != VK_RIGHT && 
        wParam != VK_UP && wParam != VK_DOWN) 
        { 
            break; 
        } 
 
        GetCursorPos(&pt); 
 
        // Convert screen coordinates to client coordinates. 
 
        ScreenToClient(hwnd, &pt); 
 
        switch (wParam) 
        { 
        // Move the cursor to reflect which 
        // arrow keys are pressed. 
 
            case VK_LEFT:               // left arrow 
                pt.x -= repeat; 
                break; 
 
            case VK_RIGHT:              // right arrow 
                pt.x += repeat; 
                break; 
 
            case VK_UP:                 // up arrow 
                pt.y -= repeat; 
                break; 
 
            case VK_DOWN:               // down arrow 
                pt.y += repeat; 
                break; 
 
            default: 
                return 0; 
        } 
 
        repeat++;           // Increment repeat count. 
 
        // Keep the cursor in the client area. 
 
        GetClientRect(hwnd, &rc); 
 
        if (pt.x >= rc.right) 
        { 
            pt.x = rc.right - 1; 
        } 
        else 
        { 
            if (pt.x < rc.left) 
            { 
                pt.x = rc.left; 
            } 
        } 
 
        if (pt.y >= rc.bottom) 
            pt.y = rc.bottom - 1; 
        else 
            if (pt.y < rc.top) 
                pt.y = rc.top; 
 
        // Convert client coordinates to screen coordinates. 
 
        ClientToScreen(hwnd, &pt); 
        SetCursorPos(pt.x, pt.y); 
        return 0; 

 
    case WM_KEYUP: 
 
        repeat = 1;            // Clear repeat count. 
        return 0; 
 
}