Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En esta sección se describen los temas siguientes.
- Creación de un cursor
- Creación de un cursor combinado alfa
- Obtención de un tamaño de cursor
- Mostrar un cursor
- Confinar un Cursor
- Uso de funciones de cursor para crear una trampa para ratones
- Usar el teclado para mover el cursor
Creación de un cursor
En el siguiente ejemplo se crean dos identificadores de cursor: uno para el cursor estándar de reloj de arena y otro para un cursor personalizado incluido como recurso en el archivo de definición de recursos de la aplicación.
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));
Las aplicaciones deben implementar cursores personalizados como recursos y usar LoadCursor, LoadCursorFromFile o LoadImage en lugar de crear el cursor en tiempo de ejecución. El uso de recursos de cursor evita la dependencia del dispositivo, simplifica la localización y permite a las aplicaciones compartir diseños de cursor.
En el ejemplo siguiente se usa la función CreateCursor para crear un cursor monocromo personalizado en tiempo de ejecución. Aquí se incluye el ejemplo para ilustrar cómo interpreta el sistema las máscaras de cursor.
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
Para crear el cursor, CreateCursor aplica la siguiente tabla de verdad a las máscaras AND y XOR .
MÁSCARA Y | Máscara XOR | Mostrar |
---|---|---|
0 | 0 | Negro |
0 | 1 | Blanco |
1 | 0 | Pantalla |
1 | 1 | Pantalla inversa |
Para obtener más información, vea Mapas de bits.
Creación de un cursor combinado alfa
Siga estos pasos para crear un cursor o icono combinado alfa en tiempo de ejecución:
- Complete una estructura de BITMAPV5HEADER , como en el ejemplo de código que sigue estos pasos, para definir un DIB combinado alfa de 32 bits por píxel (BPP).
- Llame a la función CreateDIBSection para crear una sección DIB basada en la estructura BITMAPV5HEADER que completó.
- Use el mapa de bits y la información alfa que desee para el cursor o icono combinado alfa para completar la sección DIB.
- Complete una estructura ICONINFO.
- Coloque un mapa de bits monocromático vacío en el campo hbmMask y, a continuación, coloque la sección DIB mezclada alfa en el campo hbmColor .
- Llame a la función CreateIconIndirect para crear el cursor o el icono combinado alfa.
En el código siguiente se muestra cómo crear un cursor combinado alfa. Puede usar el mismo código para crear un icono combinado alfa cambiando el miembro fIcon de la estructura ICONINFO a 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;
}
Antes de cerrar, debe usar la función DestroyCursor para destruir los cursores creados con CreateCursor o CreateIconIndirect. No es necesario destruir cursores creados por otras funciones.
Obtener el tamaño del cursor
Consulte Obtención del tamaño del icono.
Mostrar un cursor
El sistema muestra automáticamente el cursor de clase (el cursor asociado a la ventana a la que apunta el cursor). Puede asignar un cursor de clase al registrar una clase de ventana. En el ejemplo siguiente se muestra esto asignando un identificador de cursor al miembro hCursor de la estructura WNDCLASS identificada por el parámetro 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);
Cuando se registra la clase de ventana, el cursor identificado por 230 en el archivo de definición de recursos de la aplicación es el cursor predeterminado para todas las ventanas basadas en la clase .
La aplicación puede cambiar el diseño del cursor mediante la función SetCursor y especificando un identificador de cursor diferente. Sin embargo, cuando se mueve el cursor, el sistema vuelve a dibujar el cursor de clase en la nueva ubicación. Para evitar que se vuelva a dibujar el cursor de clase, debe procesar el mensaje WM_SETCURSOR . Cada vez que el cursor se mueve y la entrada del mouse no se captura, el sistema envía este mensaje a la ventana en la que se mueve el cursor.
Puede especificar diferentes cursores para diferentes condiciones al procesar WM_SETCURSOR. Por ejemplo, en el ejemplo siguiente se muestra cómo mostrar el cursor cada vez que el cursor se mueve sobre el icono de una aplicación minimizada.
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;
}
Cuando la ventana no está minimizada, el sistema muestra el cursor de clase.
Puede reemplazar un cursor de clase mediante la función SetClassLong . Esta función cambia la configuración de ventana predeterminada para todas las ventanas de una clase especificada. En el ejemplo siguiente se reemplaza el cursor de clase existente por el hCurs2
cursor.
// Change the cursor for window class represented by hwnd.
SetClassLongPtr(hwnd, // window handle
GCLP_HCURSOR, // change cursor
(LONG_PTR) hCurs2); // new cursor
Para obtener más información, vea Clases de ventana y entrada del mouse.
Confinar un cursor
En el ejemplo siguiente se limita el cursor a la ventana de la aplicación y, a continuación, se restaura el cursor a su ventana anterior. En el ejemplo se usa la función GetClipCursor para registrar el área en la que el cursor se puede mover y la función ClipCursor para limitar y restaurar el 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);
Dado que solo hay un cursor a la vez disponible en el sistema, una aplicación que limita el cursor debe restaurar el cursor antes de renunciar al control a otra ventana.
Uso de funciones de cursor para crear una trampa para ratones
En el ejemplo siguiente se usan las funciones SetCursorPos, GetCursorPos, CreateCursor, LoadCursor y SetCursor para crear una captura de mouse simple. También usa funciones de cursor y temporizador para supervisar la posición del cursor cada 10 segundos. Si la posición del cursor no ha cambiado en los últimos 10 segundos y la ventana principal de la aplicación se minimiza, la aplicación cambia el cursor y la mueve al icono del mousetrap.
Se incluye un ejemplo de una trampa para ratones similar en Iconos. Usa las funciones LoadCursor y LoadIcon en lugar de las funciones más dependientes del dispositivo CreateCursor y CreateIcon.
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;
}
}
Usar el teclado para mover el cursor
Dado que el sistema no requiere un mouse, una aplicación debe poder simular acciones del mouse con el teclado. En el ejemplo siguiente se muestra cómo lograrlo mediante las funciones GetCursorPos y SetCursorPos y mediante el procesamiento de la entrada de las teclas de dirección.
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;
}