如何显示非模式对话框并立即在其中显示信息?
我想在屏幕上显示一个无模式对话框并在其中显示一些信息。
但是,如果我按照以下方式使用它,则会出现一些问题:
function()
{
showdialog(XXX).
//heavy work.
update the dialog..
//heavy work.
update the dialog...
}
似乎显示了对话框,但它没有在其中绘制任何信息。 它仅在函数结束时绘制所有信息。
如何修改非模式对话框以便它立即显示信息?
I want to show a modeless dialog on the screen and display some information in it.
However if I use it the following way, it has some problems:
function()
{
showdialog(XXX).
//heavy work.
update the dialog..
//heavy work.
update the dialog...
}
It seems the dialog displayed, but it does not draw any information in it. It only draw all information when the function is over.
How can I modify the modeless dialog so it will display the information immediately?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以做一些事情。
(1) 您可以从 CDialog::OnInitDialog 方法内部发布消息给对话框,然后在消息处理程序中处理长函数那个发布的消息。 这样,对话框将首先显示,然后长函数将运行。
(2) 第二个选项是确保消息循环获得一些处理时间。 因此,如果您的长函数是某种循环,只需偶尔添加对 ProcessMessages 的调用,以确保消息队列保持为空:
编辑: 当然可以使用线程就是这样的情况,但是这样做并不总是没有风险和复杂性。
使用带有 GUI 的线程意味着必须处理多个消息队列,这意味着使用 PostThreadMessage 等 API,并且引入了一系列需要警惕的新问题。
有关此类问题的示例,请参阅以下链接:
http: //msdn.microsoft.com/en-us/library/ms644946(VS.85).aspx
其中说:
我在 Zeus IDE 中使用进程消息方法,它可以很好地确保 GUI 保持对用户的响应。 它还具有非常容易实现的优点。
There are a few things you can do.
(1) You could post the dialog a message from inside the CDialog::OnInitDialog method and then handle the long function in the message handler of that posted message. That way the dialog will first be displayed and then later the long function will get run.
(2) The second option is to make sure the message loop gets some processing time. So if your long function is some sort of loop just add the occasional call to the ProcessMessages to make sure the message queue is kept empty:
Edit: It certainly is possible to use threads is such a situation, but doing so is not always without risk and complexity.
Using threads with a GUI means having to deal with multiple message queues which then means using API's like PostThreadMessage and that introduces a new set of issues to be wary of.
For an example of one such issue refer to this link:
http://msdn.microsoft.com/en-us/library/ms644946(VS.85).aspx
where is says:
I use the process message approach in the Zeus IDE and it works very well at making sure the GUI remains responsive to the user. It is also has the advantage of being very easy to implement.
在 OnInitDialog 中,启动工作线程来执行计算。 从工作线程发布用户消息以更新对话框。
这优于 ProcessMessages 实现,原因如下:
用于执行计算的代码可以从它不属于的 UI 代码中分离出来。
在执行实际计算时,UI 保持响应。 ProcessMessages 允许在单个计算函数期间进行多次 UI 更新,但在实际计算过程中 UI 仍会被阻塞。
对话框代码:
工作线程:
In OnInitDialog, start a worker thread to perform the computations. Post a user message from the worker thread to update the dialog.
This is superior to the ProcessMessages implementation for several reasons:
The code for doing the calculations can be separated out of the UI code, where it does not belong.
The UI remains responsive while the actual calculations are being performed. ProcessMessages allows multiple UI updates during the single calculation function, but the UI will still be blocked during the actual calculations.
Dialog code:
The worker thread:
根据经验,繁重的计算不应该放在 GUI 线程中。 由于它是一个无模式对话框,因此该对话框不会拥有消息循环。 ProcessMessage() 解决方案可以工作,但 IMO 不是正确的方法。 我的建议是:
1)在OnInitDialog()中生成一个新线程
2)当发生有趣的事情时,让单独的线程向对话框发布消息。 这些有趣的事情之一是工作已经完成。
但请注意,这意味着您需要执行正确的同步。
As a rule of thumb, heavy computations should never be placed in the GUI thread. Since it is a modeless dialog, the dialog will not own the message loop. The ProcessMessage() solution will work, but is IMO not the right way. My suggestion is:
1) Spawn a new thread in OnInitDialog()
2) Have the separate thread post messages to the dialog when something interesting happens. One of these interesting things is that the work is done.
Note, however, that this will mean that you need to perform proper synchronization.
不要试图一次完成所有繁重的工作。 让对话框在 OnInitDialog 的 WM_APP 范围内向自己发送一条消息。 WM_APP 处理程序可以完成部分繁重的工作,然后执行另一个 PostMessage 并返回。 通过这种方式,您允许消息泵在处理块之间处理窗口消息。
Don't try to do your heavy work all at once. Have the dialog post itself a message in the WM_APP range in OnInitDialog. The WM_APP handler can do part of the heavy work, then do another PostMessage and return. In this way, you allow the message pump to process window messages in between your chunks of processing.
在 SDI 和 MDI 应用程序中,提供的 ProcessMessages() 函数不会导致为状态栏生成 ON_UPDATE_UI 消息。 状态栏通常用于报告有关“鼠标所在位置”的信息,因为它与正在查看或编辑的文档有关。 虽然 WM_MOUSEMOVE 消息将成功路由,但状态栏不会更新。 需要的是对状态栏的 OnUpdateCmdUI() 方法的显式调用 - 在泵送消息循环之后将是调用它的合理位置。
例如,在您的 CMainFrame 中添加:,
然后在 ProcessMessages 中调用它:
In SDI and MDI applications, the ProcessMessages() function provided will not cause ON_UPDATE_UI messages to be generated for the status bar. The status bar is often used to report information about "where the mouse is", as it pertains to the document being viewed or edited. While WM_MOUSEMOVE messages will be routed successfully, the status bar updates won't. What's needed is an explicit call to the status bar's OnUpdateCmdUI() method - after pumping the message loop would be a reasonable place to call it.
e.g.in your CMainFrame, add:
and then call it in ProcessMessages: