微軟知識庫有一篇文章Q131991描述了三種方法來改變基於MFC應用的鼠標光標。其中一種方法是重載CWnd::PreCreateWindow()函數注冊自己的要改變鼠標指針的窗口類。這個方法對於要始終使用一個鼠標光標的應用程序很適合。
如果在應用程序中要動態改變鼠標光標,微軟知識庫的這篇文章建議重載CWnd::OnSetCursor()來實現。但是這種方法有一個缺點,就是當設置鼠標光標及還原時都會出現令人討厭的光標閃爍。
如果應用程序中要使用幾個不同的鼠標光標,為了不發生任何光標閃爍,本文介紹一種方法:首先按照微軟知識庫文章所說重載PreCreateWindow函數,但是不要指定要使用的鼠標光標,而是使用NULL。這樣就防止了Windows或MFC針對鼠標指針做任何操作。
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// 創建自己的窗口類,窗口不設置光標,以便根據需要進行設置
if (cs.lpszClass == NULL)
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS);
return CScrollView::PreCreateWindow(cs);
}
因為窗口類沒有任何事先指定好的的鼠標指針,所以以上代碼有效地派出了光標的閃爍。(注意這段代碼創建的窗口類也沒有背景刷,所以窗口的背景色需要自己畫。為此要向函數AfxRegisterWndClass()傳遞第三個參數作為背景刷。)
光標的閃爍是消除了,但同時光標也沒了!不用擔心。在處理鼠標事件OnMouseMove時設置光標是很容易的事情。實踐證明,如果要在應用窗口中改變鼠標指針,在OnMouseMove事件處理模塊中設置光標是最方便的。
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( ??? ));
else // 普通光標指針
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
}
盡管要做一點額外的工作,但它實現了應用中不同的鼠標指針變化,同時消除了閃爍。