Application::DoEvents
不仅仅是刷新屏幕。它实际上为应用程序的 UI 线程抽取消息队列。如果您想在汇编程序中执行此操作,则需要自己泵送消息队列。但是,我不建议这样做。在任何 UI 框架中使用DoEvents
都是明确的反模式,无论它是否提供这样的功能。更多信息在这里和这里。
如果您只想确保重新绘制列表框控件,则需要使其无效并强制重新绘制。在 WinForms 中,这将是:
myListBox.Invalidate();
myListBox.Update();
在汇编程序中,您需要自己调用适当的 Win32 API 函数。特别是,您可以使用InvalidateRect
使列表框控件的客户区无效,然后UpdateWindow
确保它立即重新绘制。
我不知道 MASM 的语法,但在非托管 C++ 中,它看起来像这样:
InvalidateRect(hListBox, /* handle to your listbox control */
NULL, /* invalidate the entire client area */
TRUE); /* erase the background */
UpdateWindow(hListBox);
在大多数情况下,使窗口无效就足够了。您不需要强制立即重绘,因为下次您的应用程序处理消息时(在其常规消息循环中),它将处理一条WM_PAINT
消息并重绘控件。这不起作用的唯一原因是,如果您通过执行某种类型的长时间运行的操作来阻塞 UI 线程,而您一开始就不应该这样做——分离一个后台线程来执行计算。
在这里发送WM_SETREDRAW
消息不起作用的原因是因为这基本上设置了一个标志,指示是否允许控件重绘自身。正如链接文档所解释的,仍然需要重新绘制窗口才能看到更改。它说你可以通过调用,例如,RedrawWindow
或者做我们上面做的同样的事情来强制这样做。