天天看點

SetCursor的效果僅持續到下一個SetCursor調用

當然,SetCursor 函數對線程的影響隻會持續到該線程将光标更改為其他内容為止。任何白癡都知道,對吧?

棘手的部分是,SetCursor 可能來自一個意想不到的地方。

人們最常遇到這種情況的地方是當他們做出這樣的事情時:

// Put up the hourglass
 HCURSOR hcurPrev = SetCursor(hcurWait);
 … do some processing …
 // Restore the original cursor
 SetCursor(hcurPrev);      

上面的代碼實作這樣的邏輯:在業務操作開始之前,将光标設定為沙漏形,然後執行業務操作,最後還原光标。但是,一定要注意的是,如果在整個過程中,你調用了提取消息(Pump message)的函數(或者通過其他函數調用間接地提取了消息),則沙漏光标将立即消失并傳回到正常箭頭光标。

這是因為,當你提取并處理消息時,這會打開 WM_NCHITTEST 和 WM_SETCURSOR 等消息的大門。特别是後者,它通常會導緻光标更改,要麼是視窗本身選擇的光标,要麼是視窗類定義的預設光标(如果消息一直傳遞到 DefWindowProc 的話)。

如果你想在抽取消息時保持沙漏光标,你需要讓視窗知道 “如果需要重新設定光标,請豎起一個沙漏,而不是顯示正常的光标”。然後,該視窗必須更改其 WM_SETCURSOR處理方式,以實作這個功能。

case WM_SETCURSOR:
 if (ForceHourglass())
 {
 SetCursor(hcurWait);
 return TRUE;
 }
 …      

請注意,強制沙漏光标,隻是冰山一角。即使光标是沙漏形,視窗仍處于活動狀态,并且可以接收其他消息,如滑鼠單擊和按鍵。如果你的程式在此階段尚未準備好接收新輸入,則需要檢測這種情況,并且如果使用者在你仍在計算時不耐煩地單擊“計算”按鈕,則你需要注意不要使代碼進入某種遞歸狀态。

總結

在 Topomel Box 的開發中,我很少通過修改光标形狀來向使用者傳遞某種狀态變化的資訊。

原因是有如下幾點:

> 相對于螢幕來說,光标看起來很小,有些使用者可能不會注意到光标形狀的變化。

> 即使使用者注意到光标形狀變化了,但他可能仍然進行界面操作,這樣我們通過修改光标形狀來提示使用者的目的就被繞開了。

> 如果業務操作過程很快,則光标形狀的變化以及迅速到來的光标恢複,會呈現出一種沒有必要的光标閃爍。對于使用者來說,這種閃爍,會讓他感受到程式有那麼一絲絲的不穩定。

我們的軟體,應該讓使用者在使用過程中,感到内心的平靜。

最後

上一篇: TK1上配置VNC