Partager via


Utilisation de curseurs

Cette section décrit les rubriques suivantes.

Création d’un curseur

L’exemple suivant crée deux poignées de curseur : une pour le curseur de sablier standard et une pour un curseur personnalisé inclus en tant que ressource dans le fichier de définition de ressource de l’application.

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)); 

Les applications doivent implémenter des curseurs personnalisés en tant que ressources et utiliser LoadCursor, LoadCursorFromFile ou LoadImage plutôt que de créer le curseur au moment de l’exécution. L’utilisation de ressources de curseur évite la dépendance des appareils, simplifie la localisation et permet aux applications de partager des conceptions de curseurs.

L’exemple suivant utilise la fonction CreateCursor pour créer un curseur monochrome personnalisé au moment de l’exécution. L’exemple est inclus ici pour illustrer comment le système interprète les masques de curseur.

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 

Pour créer le curseur, CreateCursor applique le tableau de vérité suivant aux masques AND et XOR .

MASQUE ET Masque XOR Affichage
0 0 Noir
0 1 Blanc
1 0 Écran
1 1 Écran inverse

Pour plus d’informations, consultez Bitmaps.

Création d’un curseur fusionné alpha

Procédez comme suit pour créer un curseur ou une icône alpha fusionné au moment de l’exécution :

  • Effectuez une structure BITMAPV5HEADER , comme dans l’exemple de code suivant ces étapes, pour définir une DIB mixte alpha de 32 bits par pixel (BPP).
  • Appelez la fonction CreateDIBSection pour créer une section DIB basée sur la structure BITMAPV5HEADER que vous avez terminée.
  • Utilisez les informations bitmap et alpha souhaitées pour votre curseur ou icône avec fusion alpha afin de terminer la section DIB.
  • Terminez une structure ICONINFO .
  • Placez une bitmap monochrome vide dans le champ hbmMask , puis placez la section DIB fusionnée alpha dans le champ hbmColor .
  • Appelez la fonction CreateIconIndirect pour créer le curseur ou l’icône fusionné alpha.

Le code suivant montre comment créer un curseur fusionné alpha. Vous pouvez utiliser le même code pour créer une icône alpha fusionnée en modifiant le membre fIcon de la structure ICONINFO sur 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;
}

Avant de fermer, vous devez utiliser la fonction DestroyCursor pour détruire les curseurs que vous avez créés avec CreateCursor ou CreateIconIndirect. Il n’est pas nécessaire de détruire les curseurs créés par d’autres fonctions.

Obtention d’une taille de curseur

Voir Obtenir la taille de l’icône.

Affichage d’un curseur

Le système affiche automatiquement le curseur de classe (le curseur associé à la fenêtre vers laquelle le curseur pointe). Vous pouvez affecter un curseur de classe lors de l’inscription d’une classe de fenêtre. L’exemple suivant illustre cela en affectant un handle de curseur au membre hCursor de la structure WNDCLASS identifiée par le paramètre wc .

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); 

Lorsque la classe de fenêtre est inscrite, le curseur identifié par 230 dans le fichier de définition de ressource de l’application est le curseur par défaut pour toutes les fenêtres en fonction de la classe.

Votre application peut modifier la conception du curseur à l’aide de la fonction SetCursor et en spécifiant un autre handle de curseur. Toutefois, lorsque le curseur se déplace, le système redessine le curseur de classe au nouvel emplacement. Pour empêcher le redimensionnement du curseur de classe, vous devez traiter le message WM_SETCURSOR . Chaque fois que le curseur se déplace et que l’entrée de la souris n’est pas capturée, le système envoie ce message à la fenêtre dans laquelle le curseur se déplace.

Vous pouvez spécifier différents curseurs pour différentes conditions lors du traitement des WM_SETCURSOR. Par exemple, l’exemple suivant montre comment afficher le curseur chaque fois que le curseur se déplace sur l’icône d’une application réduite.

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; 
    } 

Lorsque la fenêtre n’est pas réduite, le système affiche le curseur de classe.

Vous pouvez remplacer un curseur de classe à l’aide de la fonction SetClassLong . Cette fonction modifie les paramètres de fenêtre par défaut pour toutes les fenêtres d’une classe spécifiée. L’exemple suivant remplace le curseur de classe existant par le hCurs2 curseur.

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

Pour plus d’informations, consultez Classes de fenêtre et entrée de souris.

Confisage d’un curseur

L’exemple suivant limite le curseur à la fenêtre de l’application, puis restaure le curseur dans sa fenêtre précédente. L’exemple utilise la fonction GetClipCursor pour enregistrer la zone dans laquelle le curseur peut déplacer et la fonction ClipCursor pour limiter et restaurer le curseur.

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); 

Étant donné qu’il n’existe qu’un seul curseur à la fois disponible dans le système, une application qui limite le curseur doit restaurer le curseur avant de renoncer au contrôle dans une autre fenêtre.

Utilisation des fonctions de curseur pour créer un souristrap

L’exemple suivant utilise les fonctions SetCursorPos, GetCursorPos, CreateCursor, LoadCursor et SetCursor pour créer une souris simple. Il utilise également des fonctions de curseur et de minuteur pour surveiller la position du curseur toutes les 10 secondes. Si la position du curseur n’a pas changé au cours des 10 dernières secondes et que la fenêtre principale de l’application est réduite, l’application modifie le curseur et le déplace vers l’icône de la souris.

Un exemple pour une souricière similaire est inclus dans Icônes. Il utilise les fonctions LoadCursor et LoadIcon au lieu des fonctions CreateCursor et CreateIcon dépendantes de l’appareil.

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; 
    } 
} 

Utilisation du clavier pour déplacer le curseur

Étant donné que le système ne nécessite pas de souris, une application doit être en mesure de simuler des actions de souris avec le clavier. L’exemple suivant montre comment effectuer cette opération à l’aide des fonctions GetCursorPos et SetCursorPos et en traitant l’entrée à partir des touches de direction.

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; 
 
}