【问题标题】:Program Freezes on MessageBox()程序在 MessageBox() 上冻结
【发布时间】:2011-09-10 05:26:16
【问题描述】:

问题出在:主 GUI 线程正在向另一个 GUI 线程执行 SendMessage(是的,有多个 GUI 线程,不幸的是这无法改变)。当第二个 GUI 线程接收到 SendMessage 时,它​​可能决定显示一个消息框。有时,MessageBox 会“冻结”整个应用程序。

更具体地说,消息框出现了,但整个 GUI 被挂起(用户输入在任何地方都不起作用)。

我已经用调试器验证了第二个 GUI 线程在 user32.dll 中定义的 DialogBox2() 函数中旋转。我可以在反汇编中看到正在执行消息泵(我看到 IsDialogMessage/TranslateMessage/DispatchMessage 被调用)。使用 spy++,我看不到消息对话框窗口正在处理任何消息。我确实看到消息在主 GUI 窗口上得到处理(例如 WM_SETCURSOR,尽管我不认为它们正在被处理,因为我相信 SendMessage 不会执行消息泵)。

第二个线程正在执行作为 MFC 扩展 DLL 一部分的代码,如果这很重要的话。

我尝试过使用 AfxMessageBox() / CWnd::MessageBox / ::MessageBox(NULL parent window,...)。都表现出同样的问题。

有没有人见过类似的东西?

谢谢, 安德鲁

【问题讨论】:

  • 我在你问题的第一句话中发现了问题,所以我不知道为什么我应该进一步阅读。您正在使用多个 GUI 线程,您知道这是一个坏主意,并且您想知道为什么会看到不良行为?嗯。
  • 更重要的是,MessageBox 是一个阻塞调用,无论您是否使用由 MFC 封装的调用。这意味着它会阻止消息被处理,与您描述的行为一致。
  • 我了解 MessageBox 正在阻塞。 MessageBox 不应该被冻结(例如,我应该能够单击 OK 将其关闭)。正如我所说,应用程序不能更改为单个 GUI 线程。我同意这是个坏主意,但不是我写的。
  • 我尝试使用 NULL 父级调用 MessageBox,以尝试排除这种可能性。
  • msdn.microsoft.com/en-us/library/ms644928(v=vs.85).aspx 和 Raymond Chen 的博客有助于阅读。例如,窗口和消息队列与创建线程相关联。

标签: windows visual-studio winapi visual-c++ mfc


【解决方案1】:

一定是阻塞其中一个 GUI 线程导致了问题。

试试这个:

将 ::SendMesage 替换为 ::PostMessage 后跟 ::MsgWaitForMultipleObjects 循环。您将需要传递一个事件句柄,该句柄会在消息框关闭时发出信号。

它可能会解决问题。

请注意您在 ::MsgWaitForMultipleObjects 循环中发送的消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多