正如 @Heinz Traub 所说,问题来自于在 RegisterClass
或 RegisterClassEx
调用中定义的光标。你可能有以下代码:
BOOL CMyWnd::RegisterWindowClass()
{
WNDCLASS wndcls;
// HINSTANCE hInst = AfxGetInstanceHandle();
HINSTANCE hInst = AfxGetResourceHandle();
if (!(::GetClassInfo(hInst, _T("MyCtrl"), &wndcls)))
{
// otherwise we need to register a new class
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = _T("MyCtrl");
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
其中wndcls.hCursor
指定了在抛出WM_SETCURSOR
消息时使用的光标;它会在每次鼠标移动时发生,而不仅仅是一次。
我通过以下方式解决了类似的问题:
在类的消息映射中添加一个WM_SETCURSOR
消息的条目:
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
//... other messages
ON_WM_SETCURSOR()
END_MESSAGE_MAP()
添加方法OnSetCursor
,该方法将覆盖父类的实现:
BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (SomeCondition())
return FALSE;
return __super::OnSetCursor(pWnd, nHitTest, message);
}
解释:当SomeCondition()
为真时,您将不会调用父类的实现。也许您希望始终具有不被父类行为取代的光标,因此您只需要一个更短的方法:
BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
return FALSE;
}
而在头文件中该方法的声明为:
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);