天天看点

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