在线程控制上等待光标

时间:2010-07-04 08:40:11

标签: winapi multithreading cursor

我为三个线程创建了三个复选框控件,每个控件都会通过选中一个复选框控件来启动。当用户取消选中复选框时,我想打开其他线程控件上的等待光标,而不是在一个时间实例中完全禁用它们,让特定线程停止。

如何为特定控件设置IDC_WAIT游标ID,或者我应该让用户按顺序自由启动/停止多个线程?

2 个答案:

答案 0 :(得分:5)

许多人不明白游戏是如何“等待”的......我犹豫说不起作用。

消息的历史真的很明显:WM_SETCURSOR自Windows 3.1以来就已存在 - 一个16位的协作多任务操作系统。因为只有一个线程(合作多任务) - 当应用程序“忙”时,非驱动程序级代码不可能运行。因此,对“忙”游标的处理是这样的:

WM_SETCURSOR将始终以适当的“非忙”光标进行响应。

任何“忙碌”的代码都会如下:

SetCursor(hHourglass);
DoBusyThing();
SetCursor(hRegular);

这会将硬件光标更改为沙漏 - DoBusyThing将占用该线程,并且WM_SETCURSOR消息在退出之前不会被处理,也不会被处理。

Win32稍微改变了语义 - 它在每个线程上记住最后一个光标在该线程集上的一个窗口 - 允许Windows 3.1的协作逻辑在异步多任务Win32环境中工作:如果线程忙(即不抽取消息)该线程上的窗口的WM_SETCURSOR消息将被卡在消息队列中 - 因此沙漏光标仍然是被阻塞线程拥有的所有窗口的默认光标,直到繁忙操作完成并且线程返回到消息处理循环。

当然,在我们不再阻止UI线程的现代世界中,这种逻辑都不能很好地工作: - 繁忙的工作现在偏移到工作线程,这意味着UI线程正在调度WM_SETCURSOR消息并重置忙碌光标回到类光标。

这不是一个真正的问题:等待游标总是暗示应用程序没有响应,并且正在运行的UI线程+繁忙的工作线程不是这个反馈机制真正设计或打算涵盖的内容。

我认为正确的做法是将光标保持单独,并以其他方式反映用户界面(停止按钮旁边的图标?)进一步的线程不能/不应该启动。

答案 1 :(得分:2)

处理WM_SETCURSOR(父窗口通常有机会为其子窗口设置光标,如果子窗口有特殊处理,则必须将其子类化并在那里处理WM_SETCURSOR)