이 섹션에서는 다음 항목에 대해 설명합니다.
- 커서 만들기
- 알파 혼합 커서 만들기
- 커서 크기 가져오기
- 커서 표시
- 커서 제약
- 커서 함수를 사용하여 쥐덫 만들기
- 키보드를 사용하여 커서 이동
커서 만들기
다음 예제에서는 두 개의 커서 핸들을 만듭니다. 하나는 표준 모래 시계 커서용이고 다른 하나는 애플리케이션의 리소스 정의 파일에 리소스로 포함된 사용자 지정 커서용입니다.
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));
애플리케이션은 사용자 지정 커서를 리소스로 구현하고 런타임에 커서를 만드는 대신 LoadCursor, LoadCursorFromFile또는 LoadImage 사용해야 합니다. 커서 리소스를 사용하면 디바이스 의존성이 방지되고 지역화가 간소화되며 애플리케이션에서 커서 디자인을 공유할 수 있습니다.
다음 예제에서는 CreateCursor 함수를 사용하여 런타임에 사용자 지정 단색 커서를 만듭니다. 이 예제는 시스템에서 커서 마스크를 해석하는 방법을 설명하기 위해 여기에 포함되어 있습니다.
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
커서를 만들려면 CreateCursorAND 및 XOR 마스크에 다음 진리 테이블을 적용합니다.
AND 마스크 | XOR 마스크 | 디스플레이 |
---|---|---|
0 | 0 | 검정 |
0 | 1 | 하얀 |
1 | 0 | 화면 |
1 | 1 | 역방향 화면 |
자세한 내용은 비트맵참조하세요.
알파 혼합 커서 만들기
다음 단계에 따라 런타임에 알파 혼합 커서 또는 아이콘을 만듭니다.
- 다음 단계의 코드 예제와 같이 BITMAPV5HEADER 구조를 완료하여 BPP(픽셀당 32비트) 알파 혼합 DIB를 정의합니다.
- CreateDIBSection 함수를 호출하여 완료한 BITMAPV5HEADER 구조에 따라 DIB 섹션을 만듭니다.
- 알파 혼합 커서 또는 아이콘에 원하는 비트맵 및 알파 정보를 사용하여 DIB 섹션을 완료합니다.
- ICONINFO 구조를 완료합니다.
- hbmMask 필드에 빈 단색 비트맵을 배치한 다음, 알파 혼합 DIB 섹션을 hbmColor 필드에 배치합니다.
- CreateIconIndirect 함수를 호출하여 알파 혼합 커서 또는 아이콘을 만듭니다.
다음 코드에서는 알파 혼합 커서를 만드는 방법을 보여 줍니다. 동일한 코드를 사용하여 ICONINFO 구조체의 fIcon 멤버를 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;
}
닫기 전에 DestroyCursor 함수를 사용하여 CreateCursor 또는 CreateIconIndirect를 사용하여 만든 커서를 반드시 삭제해야 합니다. 다른 함수에서 만든 커서를 삭제할 필요는 없습니다.
커서 크기 가져오기
아이콘 크기가져오기를 참조하세요.
커서 표시
시스템에서 자동으로 클래스 커서(커서가 가리키는 창과 연결된 커서)를 표시합니다. 창 클래스를 등록하는 동안 클래스 커서를 할당할 수 있습니다. 다음 예제에서는 wc 매개 변수로 식별된 WNDCLASS 구조체의 hCursor 멤버에 커서 핸들을 할당하여 이를 보여 줍니다.
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);
창 클래스가 등록되면 애플리케이션의 리소스 정의 파일에서 230으로 식별되는 커서는 클래스를 기반으로 하는 모든 창에 대한 기본 커서입니다.
애플리케이션은 SetCursor 함수를 사용하고 다른 커서 핸들을 지정하여 커서 디자인을 변경할 수 있습니다. 그러나 커서가 이동하면 시스템은 새 위치에서 클래스 커서를 다시 그어 옵니다. 클래스 커서가 다시 그려지는 것을 방지하려면 WM_SETCURSOR 메시지를 처리해야 합니다. 커서가 이동하고 마우스 입력이 캡처되지 않을 때마다 시스템은 커서가 이동하는 창으로 이 메시지를 보냅니다.
WM_SETCURSOR처리하는 동안 다양한 조건에 대해 다른 커서를 지정할 수 있습니다. 예를 들어 다음 예제에서는 커서가 최소화된 애플리케이션의 아이콘 위로 이동할 때마다 커서를 표시하는 방법을 보여 줍니다.
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;
}
창이 최소화되지 않으면 시스템에서 클래스 커서를 표시합니다.
SetClassLong 함수를 사용하여 클래스 커서를 바꿀 수 있습니다. 이 함수는 지정된 클래스의 모든 창에 대한 기본 창 설정을 변경합니다. 다음 예제에서는 기존 클래스 커서를 hCurs2
커서로 바꿉니다.
// Change the cursor for window class represented by hwnd.
SetClassLongPtr(hwnd, // window handle
GCLP_HCURSOR, // change cursor
(LONG_PTR) hCurs2); // new cursor
자세한 내용은 창 클래스 및 마우스 입력 참조하세요.
커서 제한
다음 예제에서는 커서를 애플리케이션의 창으로 제한한 다음 커서를 이전 창으로 복원합니다. 이 예제에서는 GetClipCursor 함수를 사용하여 커서가 이동할 수 있는 영역과 ClipCursor 함수를 기록하여 커서를 제한하고 복원합니다.
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);
시스템에서 한 번에 하나의 커서만 사용할 수 있으므로 커서를 제한하는 애플리케이션은 컨트롤을 다른 창으로 포기하기 전에 커서를 복원해야 합니다.
커서 함수를 사용하여 마우스스트랩 만들기
다음 예제에서는 SetCursorPos, GetCursorPos, CreateCursor, LoadCursor및 SetCursor 함수를 사용하여 간단한 마우스 트랩을 만듭니다. 또한 커서 및 타이머 함수를 사용하여 10초마다 커서의 위치를 모니터링합니다. 지난 10초 동안 커서 위치가 변경되지 않고 애플리케이션의 주 창이 최소화된 경우 애플리케이션은 커서를 변경하고 마우스스트랩 아이콘으로 이동합니다.
유사한 마우스 트랩에 대한 예제는 아이콘포함되어 있습니다. 더 많은 디바이스 종속 CreateCursor 및 CreateIcon 함수 대신 LoadCursor 및 LoadIcon 함수를 사용합니다.
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;
}
}
키보드를 사용하여 커서 이동
시스템에 마우스가 필요하지 않으므로 애플리케이션은 키보드로 마우스 동작을 시뮬레이션할 수 있어야 합니다. 다음 예제에서는 GetCursorPos 및 SetCursorPos 함수를 사용하고 화살표 키의 입력을 처리하여 이를 달성하는 방법을 보여 줍니다.
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;
}