等待线程控制上的光标
我为三个线程创建了三个复选框控件,每个线程都通过检查复选框控件开始。当用户取消选中复选框时,我想打开其他线程控件上的等待光标,而不是在一段时间内完全禁用它们,让特定线程停止。
如何为特定控件设置 IDC_WAIT 游标 ID,或者我应该让用户按顺序自由启动/停止多个线程?
I have created three checkbox controls for three threads and each would start by checking a checkbox control. When a user unchecks a checkbox, I want to turn on the Wait Cursor on the other thread controls rather than completely disabling them for an instance of time, letting a particular thread to stop.
How would you set a IDC_WAIT cursor id for a specific control or should i let the user to freely start/stop multiple threads in order?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
许多人不明白“等待”光标是如何......我犹豫是否要说是为了工作。
然而,该消息的历史确实很能说明问题:WM_SETCURSOR 自 Windows 3.1(一种 16 位协作多任务操作系统)以来就已存在。因为只有一个线程(协作多任务) - 当应用程序“忙”时,非驱动程序级别的代码不可能运行。因此,对“忙”游标的处理如下:
WM_SETCURSOR总是以适当的“非忙”游标进行响应。
任何将要“忙”的代码都将如下所示:
这会将硬件光标更改为沙漏 - DoBusyThing 将占用线程,并且 WM_SETCURSOR 消息在退出之前不会也无法处理。
Win32 稍微改变了语义 - 它在每个线程上记住最后一个光标,该线程集上的一个窗口 - 允许 Windows 3.1 的协作逻辑在异步多任务 Win32 环境中工作: 如果线程繁忙(即没有泵送消息) ) 该线程上窗口的 WM_SETCURSOR 消息将“卡在”消息队列中 - 因此沙漏光标仍然是被阻止线程拥有的所有窗口的默认光标,直到繁忙操作完成并且线程返回到消息处理循环。
当然,在我们不再阻塞 UI 线程的现代世界中,这些逻辑都不能很好地工作: - 繁忙的工作现在被偏移到工作线程,这意味着 UI 线程正在分派 WM_SETCURSOR 消息并将繁忙的光标重置回类光标。
这并不是真正的问题:等待光标始终暗示应用程序没有响应,并且正常运行的 UI 线程 + 繁忙的工作线程并不是此反馈机制真正设计或旨在涵盖的内容。
我认为正确的做法是不理会光标,并以其他方式反映用户界面(停止按钮旁边的图标?),从而不能/不应该启动更多线程。
Many people do not understand how "wait" cursors are ... I hesitate to say indended to work.
The history of the message is really telling however: WM_SETCURSOR has existed since Windows 3.1 - a 16 bit co-operatively multitasked operating system. Because there was only a single thread (Being co-operatively multitasked) - it was not possible for non driver level code to run while an application was "busy". Hence, the handling for "busy" cursors was like this:
WM_SETCURSOR would always respond with the appropriate "non busy" cursor.
Any code that was going to be "busy" would look like:
This would change the hardware cursor to the hourglass - DoBusyThing would occupy the thread, and WM_SETCURSOR messages would not, and could not, be handled until it exited.
Win32 changed the semantics a little - It remembers on each thread the last cursor a window on that thread set - allowing the co-operative logic of Windows 3.1 to work in the casynchronously multitasked Win32 environment: If a thread is busy (i.e. not pumping messages) WM_SETCURSOR messages for windows on that thread will just get "stuck" in the message queue - hence the hourglass cursor remains the default cursor for all windows owned by the blocked thread, until the busy operation completes and the thread returns to the message processing loop.
Of course, none of this logic works really well in the modern world where we no longer block UI threads:- The busy work is now offset to a worker thread, meaning the UI thread is dispatching WM_SETCURSOR messages and resetting the busy cursor back to the class cursor.
This is not really a problem: The wait cursor have always implied that the application is non responsive and a functioning UI thread + busy worker thread is not what this feedback mechanism is really designed or intended to cover.
I think the correct thing to do would be to leave the cursor alone, and reflect on the UI some other way (stop icons next to the buttons?) that further threads can not / should not be launched.
处理 WM_SETCURSOR (父窗口通常有机会为其子窗口设置光标,如果子窗口有特殊处理,则必须对其进行子类化并在那里处理 WM_SETCURSOR)
Handle WM_SETCURSOR (The parent window usually gets the chance to set the cursor for its children, if the child window has special handling, you would have to subclass it and handle WM_SETCURSOR there)