很简单,就是在WinProc函数里增加一个WM_ACTIVATE消息处理,然后调用ClipCursor来限制鼠标的可移动范围.
好像WIN32没有直接将RECT从client坐标转换成screen坐标的,所以我自己写了这么个函数.
当然这里给出的代码并不是高效的,GetSystemMetrics不应该在WinProc里调用,但这里只是给出了一种解决方案,暂不考虑代码执行效率的问题.
//-------------------------------------------------------------------------
// Translates rect from client coordinate to screen coordinate.
//-------------------------------------------------------------------------
void RectFromClientToScreen(LPRECT rect)
{
POINT tmp;
tmp.x = rect->left;
tmp.y = rect->top;
ClientToScreen(g_mainWindowHandle, &tmp);
rect->left = tmp.x;
rect->top = tmp.y;
tmp.x = rect->right;
tmp.y = rect->bottom;
ClientToScreen(g_mainWindowHandle, &tmp);
rect->right = tmp.x;
rect->bottom = tmp.y;
}
//-------------------------------------------------------------------------
// Main windows event procedure.
//-------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; // used in WM_APINT
HDC hdc; // handle to a device context
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
RECT screenRect = {0, 0, screenWidth, screenHeight};
RECT clientRect;
// what is the message
switch (msg)
{
case WM_CREATE:
// do initialization stuff here
return 0;
case WM_PAINT:
// start painting
hdc = BeginPaint(hwnd, &ps);
// end painting
EndPaint(hwnd, &ps);
return 0;
case WM_ACTIVATE:
if(LOWORD(wParam) == WA_ACTIVE)
{
GetClientRect(g_mainWindowHandle, &clientRect);
RectFromClientToScreen(&clientRect);
ClipCursor(&clientRect);
}
else if(LOWORD(wParam) == WA_INACTIVE)
ClipCursor(&screenRect);
break;
case WM_DESTROY:
// kill the application
PostQuitMessage(0);
return 0;
}
// process any messages that we did not take care of
return DefWindowProc(hwnd, msg, wParam, lParam);
}