0

当程序在 c++、c#、vb.net 中进行计算时,您可以使用application::doevents()刷新屏幕,以免屏幕冻结。你怎么能在组装特定的masm中做到这一点

我试着把

invoke SendMessage, hWin, WM_SETREDRAW, 0, 0 
invoke SendMessage, hWin, WM_SETREDRAW, 1, 0 

在我程序的循环部分,但它不起作用。

我也试过

invoke SendMessage, hWin, WM_SETREDRAW, 1, 0

但这也不起作用

4

1 回答 1

1

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或者做我们上面做的同样的事情来强制这样做。

于 2013-04-02T23:44:26.380 回答