Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ta sekcja zawiera przykłady kodu dla następujących zadań:
- Tworzenie i wyświetlanie karetki
- ukrywanie kursora
- Niszczenie karetki
- Dostosowywanie czasu mrugania
- przetwarzanie danych wejściowych klawiatury
Tworzenie i wyświetlanie karetki
Po otrzymaniu fokusu klawiatury okno powinno utworzyć i wyświetlić kursor. Użyj funkcji CreateCaret aby utworzyć kursor w danym oknie. Następnie możesz wywołać SetCaretPos, aby ustawić bieżące położenie kursora i ShowCaret, aby kursor był widoczny.
System wysyła komunikat WM_SETFOCUS do okna odbierającego fokus klawiatury; w związku z tym aplikacja powinna utworzyć i wyświetlić kursor podczas przetwarzania tego komunikatu.
HWND hwnd, // window handle
int x; // horizontal coordinate of cursor
int y; // vertical coordinate of cursor
int nWidth; // width of cursor
int nHeight; // height of cursor
char *lpszChar; // pointer to character
case WM_SETFOCUS:
// Create a solid black caret.
CreateCaret(hwnd, (HBITMAP) NULL, nWidth, nHeight);
// Adjust the caret position, in client coordinates.
SetCaretPos(x, y);
// Display the caret.
ShowCaret(hwnd);
break;
Aby utworzyć kursor na podstawie mapy bitowej, należy określić uchwyt mapy bitowej podczas korzystania z CreateCaret. Za pomocą aplikacji graficznej można utworzyć mapę bitową i kompilator zasobów, aby dodać mapę bitową do zasobów aplikacji. Aplikacja może następnie użyć funkcji LoadBitmap, aby załadować uchwyt mapy bitowej. Można na przykład zastąpić wiersz CreateCaret w poprzednim przykładzie następującymi wierszami, aby utworzyć kursor mapy bitowej.
// Load the application-defined caret resource.
hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));
// Create a bitmap caret.
CreateCaret(hwnd, hCaret, 0, 0);
Alternatywnie możesz użyć funkcji CreateBitmap lub CreateDIBitmap, aby pobrać uchwyt mapy bitowej kursora. Aby uzyskać więcej informacji na temat map bitowych, zobacz Mapy bitowe.
Jeśli aplikacja określa uchwyt mapy bitowej, CreateCaret ignoruje parametry szerokości i wysokości. Mapa bitowa definiuje rozmiar karetki.
Ukrywanie kursora
Za każdym razem, gdy aplikacja rysuje ekran na nowo podczas przetwarzania komunikatu innego niż WM_PAINT, musi uczynić kursor niewidocznym za pomocą funkcji HideCaret. Po zakończeniu rysowania w aplikacji, ponownie wyświetl kursor, używając funkcji ShowCaret. Jeśli aplikacja przetwarza komunikat WM_PAINT, nie jest konieczne ukrycie i ponowne wyświetlenie kursora, ponieważ ta funkcja wykonuje to automatycznie.
Poniższy przykładowy kod pokazuje, jak można sprawić, by aplikacja ukrywała kursor podczas rysowania znaku na ekranie i podczas przetwarzania komunikatu WM_CHAR.
HWND hwnd, // window handle
HDC hdc; // device context
case WM_CHAR:
switch (wParam)
{
case 0x08:
// Process a backspace.
break;
case 0x09:
// Process a tab.
break;
case 0x0D:
// Process a carriage return.
break;
case 0x1B:
// Process an escape.
break;
case 0x0A:
// Process a linefeed.
break;
default:
// Hide the caret.
HideCaret(hwnd);
// Draw the character on the screen.
hdc = GetDC(hwnd);
SelectObject(hdc,
GetStockObject(SYSTEM_FIXED_FONT));
TextOut(hdc, x, y, lpszChar, 1);
ReleaseDC(hwnd, hdc);
// Display the caret.
ShowCaret(hwnd);
}
Jeśli aplikacja wywołuje funkcję HideCaret kilka razy bez wywoływania ShowCaret, kursor nie będzie wyświetlany, dopóki aplikacja nie wywoła również ShowCaret taką samą liczbę razy.
Niszczenie karetki
Gdy okno utraci fokus klawiatury, system wysyła komunikat WM_KILLFOCUS do okna. Aplikacja powinna zniszczyć karetę podczas przetwarzania tego komunikatu przy użyciu funkcji DestroyCaret. Poniższy kod pokazuje, jak zniszczyć kursor w oknie, które nie jest już aktywne pod wpływem klawiatury.
case WM_KILLFOCUS:
// The window is losing the keyboard focus, so destroy the caret.
DestroyCaret();
break;
Dostosowywanie czasu migania
W 16-bitowym systemie Windows aplikacja oparta na systemie Windows może wywołać funkcję GetCaretBlinkTime, aby zapisać bieżący czas, a następnie wywołać funkcję SetCaretBlinkTime, aby dostosować czas podczas przetwarzania komunikatu WM_SETFOCUS. Aplikacja przywróci zapisany czas do korzystania z innych aplikacji przez wywołanie SetCaretBlinkTime podczas przetwarzania komunikatu WM_KILLFOCUS. Jednak ta technika nie działa w środowiskach wielowątkowych. W szczególności dezaktywacja jednej aplikacji nie jest synchronizowana z aktywacją innej aplikacji, dzięki czemu w przypadku zawieszenia jednej aplikacji można nadal aktywować inną aplikację.
Aplikacje powinny uwzględniać czas migania wybrany przez użytkownika. Funkcja SetCaretBlinkTime powinna być wywoływana tylko przez aplikację, która umożliwia użytkownikowi ustawienie czasu.
Przetwarzanie danych wejściowych klawiatury
W poniższym przykładzie pokazano, jak używać kursora w prostym edytorze tekstów. W przykładzie położenie karetki jest aktualizowane, gdy użytkownik wpisuje znaki do drukowania i używa różnych kluczy do przechodzenia przez obszar klienta.
#define TEXTMATRIX(x, y) *(pTextMatrix + (y * nWindowCharsX) + x)
// Global variables.
HINSTANCE hinst; // current instance
HBITMAP hCaret; // caret bitmap
HDC hdc; // device context
PAINTSTRUCT ps; // client area paint info
static char *pTextMatrix = NULL; // points to text matrix
static int nCharX, // width of char. in logical units
nCharY, // height of char. in logical units
nWindowX, // width of client area
nWindowY, // height of client area
nWindowCharsX, // width of client area
nWindowCharsY, // height of client area
nCaretPosX, // x-position of caret
nCaretPosY; // y-position of caret
static UINT uOldBlink; // previous blink rate
int x, y; // coordinates for text matrix
TEXTMETRIC tm; // font information
LONG APIENTRY MainWndProc(
HWND hwnd, // window handle
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{
switch (message)
{
case WM_CREATE:
// Select a fixed-width system font, and get its text metrics.
hdc = GetDC(hwnd);
SelectObject(hdc,
GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc, &tm);
ReleaseDC(hwnd, hdc);
// Save the avg. width and height of characters.
nCharX = tm.tmAveCharWidth;
nCharY = tm.tmHeight;
return 0;
case WM_SIZE:
// Determine the width of the client area, in pixels
// and in number of characters.
nWindowX = LOWORD(lParam);
nWindowCharsX = max(1, nWindowX/nCharX);
// Determine the height of the client area, in
// pixels and in number of characters.
nWindowY = HIWORD(lParam);
nWindowCharsY = max(1, nWindowY/nCharY);
// Clear the buffer that holds the text input.
if (pTextMatrix != NULL)
free(pTextMatrix);
// If there is enough memory, allocate space for the
// text input buffer.
pTextMatrix = malloc(nWindowCharsX * nWindowCharsY);
if (pTextMatrix == NULL)
ErrorHandler("Not enough memory.");
else
for (y = 0; y < nWindowCharsY; y++)
for (x = 0; x < nWindowCharsX; x++)
TEXTMATRIX(x, y) = ' ';
// Move the caret to the origin.
SetCaretPos(0, 0);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME: // Home
nCaretPosX = 0;
break;
case VK_END: // End
nCaretPosX = nWindowCharsX - 1;
break;
case VK_PRIOR: // Page Up
nCaretPosY = 0;
break;
case VK_NEXT: // Page Down
nCaretPosY = nWindowCharsY -1;
break;
case VK_LEFT: // Left arrow
nCaretPosX = max(nCaretPosX - 1, 0);
break;
case VK_RIGHT: // Right arrow
nCaretPosX = min(nCaretPosX + 1,
nWindowCharsX - 1);
break;
case VK_UP: // Up arrow
nCaretPosY = max(nCaretPosY - 1, 0);
break;
case VK_DOWN: // Down arrow
nCaretPosY = min(nCaretPosY + 1,
nWindowCharsY - 1);
break;
case VK_DELETE: // Delete
// Move all the characters that followed the
// deleted character (on the same line) one
// space back (to the left) in the matrix.
for (x = nCaretPosX; x < nWindowCharsX; x++)
TEXTMATRIX(x, nCaretPosY) =
TEXTMATRIX(x + 1, nCaretPosY);
// Replace the last character on the
// line with a space.
TEXTMATRIX(nWindowCharsX - 1,
nCaretPosY) = ' ';
// The application will draw outside the
// WM_PAINT message processing, so hide the caret.
HideCaret(hwnd);
// Redraw the line, adjusted for the
// deleted character.
hdc = GetDC(hwnd);
SelectObject(hdc,
GetStockObject(SYSTEM_FIXED_FONT));
TextOut(hdc, nCaretPosX * nCharX,
nCaretPosY * nCharY,
&TEXTMATRIX(nCaretPosX, nCaretPosY),
nWindowCharsX - nCaretPosX);
ReleaseDC(hwnd, hdc);
// Display the caret.
ShowCaret(hwnd);
break;
}
// Adjust the caret position based on the
// virtual-key processing.
SetCaretPos(nCaretPosX * nCharX,
nCaretPosY * nCharY);
return 0;
case WM_CHAR:
switch (wParam)
{
case 0x08: // Backspace
// Move the caret back one space, and then
// process this like the DEL key.
if (nCaretPosX > 0)
{
nCaretPosX--;
SendMessage(hwnd, WM_KEYDOWN,
VK_DELETE, 1L);
}
break;
case 0x09: // Tab
// Tab stops exist every four spaces, so add
// spaces until the user hits the next tab.
do
{
SendMessage(hwnd, WM_CHAR, ' ', 1L);
} while (nCaretPosX % 4 != 0);
break;
case 0x0D: // Carriage return
// Go to the beginning of the next line.
// The bottom line wraps around to the top.
nCaretPosX = 0;
if (++nCaretPosY == nWindowCharsY)
nCaretPosY = 0;
break;
case 0x1B: // Escape
case 0x0A: // Linefeed
MessageBeep((UINT) -1);
break;
default:
// Add the character to the text buffer.
TEXTMATRIX(nCaretPosX, nCaretPosY) =
(char) wParam;
// The application will draw outside the
// WM_PAINT message processing, so hide the caret.
HideCaret(hwnd);
// Draw the character on the screen.
hdc = GetDC(hwnd);
SelectObject(hdc,
GetStockObject(SYSTEM_FIXED_FONT));
TextOut(hdc, nCaretPosX * nCharX,
nCaretPosY * nCharY,
&TEXTMATRIX(nCaretPosX, nCaretPosY), 1);
ReleaseDC(hwnd, hdc);
// Display the caret.
ShowCaret(hwnd);
// Prepare to wrap around if you reached the
// end of the line.
if (++nCaretPosX == nWindowCharsX)
{
nCaretPosX = 0;
if (++nCaretPosY == nWindowCharsY)
nCaretPosY = 0;
}
break;
}
// Adjust the caret position based on the
// character processing.
SetCaretPos(nCaretPosX * nCharX,
nCaretPosY * nCharY);
return 0;
case WM_PAINT:
// Draw all the characters in the buffer, line by line.
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc,
GetStockObject(SYSTEM_FIXED_FONT));
for (y = 0; y < nWindowCharsY; y++)
TextOut(hdc, 0, y * nCharY, &TEXTMATRIX(0, y),
nWindowCharsX);
EndPaint(hwnd, &ps);
case WM_SETFOCUS:
// The window has the input focus. Load the
// application-defined caret resource.
hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));
// Create the caret.
CreateCaret(hwnd, hCaret, 0, 0);
// Adjust the caret position.
SetCaretPos(nCaretPosX * nCharX,
nCaretPosY * nCharY);
// Display the caret.
ShowCaret(hwnd);
break;
case WM_KILLFOCUS:
// The window is losing the input focus,
// so destroy the caret.
DestroyCaret();
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return NULL;
}