Microsoft 知識庫文件 Q131991 介紹了三種在 MFC 應用程式中變更滑鼠游標的方法。若應用程式始終使用單一游標,覆寫 CWnd::PreCreateWindow() 註冊自訂視窗類別最為合適。但若需動態切換多種游標,文件建議覆寫 CWnd::OnSetCursor(),然而這會導致游標在設定與還原時產生明顯閃爍。
關鍵在於「不讓系統預設處理游標」。在 PreCreateWindow 中註冊視窗類別時,刻意將游標設為 NULL,阻止 Windows 或 MFC 對游標進行任何預設操作:
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs) {
// 註冊自訂視窗類別,不指定游標(傳 NULL)
if (cs.lpszClass == NULL)
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS);
return CScrollView::PreCreateWindow(cs);
}
此做法有效杜絕了閃爍,但也意味著視窗類別沒有預設游標與背景筆刷。背景繪製需自行處理(可透過 AfxRegisterWndClass 的第三個參數指定背景筆刷)。
游標消失後,改在滑鼠移動事件 OnMouseMove 中根據應用程式當前操作模式,呼叫 ::SetCursor 設定對應游標。實證這是最方便、無閃爍的動態游標切換方式:
void CMyView::OnMouseMove(UINT nFlags, CPoint point) {
// 依據目前操作模式設定游標
if (m_nOperation == OPERATION_1)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
else if (m_nOperation == OPERATION_2)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM)); // 範例游標
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
}
雖需額外撰寫判斷邏輯,卻能完美實現多種游標無縫切換,且徹底消除閃爍,提升使用者體驗。