正如@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);