【问题标题】:Windows MessageBox ignoring WM_CLOSEWindows MessageBox 忽略 WM_CLOSE
【发布时间】:2013-07-02 13:37:24
【问题描述】:

我们有一个遗留的 C Windows 应用程序,当发生致命连接错误时,它会通过 MessageBox 调用弹出一个模式窗口。我们的网络工程师可能会同时运行许多这样的应用程序。有时,网络故障会导致这些应用程序正在处理的连接同时失败。

在 Windows 7 上,从任务栏中选择“关闭所有窗口”功能确实有效,因为模式对话框似乎没有处理 WM_QUIT 消息。我通常在 Linux 系统上工作,但我的 MSDN 研究表明,我可以捕获和处理此消息的唯一方法是创建自己的对话框并自己处理消息。

我担心我忽略了一个更简单的解决方案,谁能提供替代方案?

【问题讨论】:

  • 若要关闭窗口,请发送WM_CLOSE,如果它是应用程序的主窗口,应用程序也会结束。 WM_QUIT 是结束整个应用程序并关闭它拥有的所有窗口。
  • "...从任务栏中选择“关闭所有窗口”功能确实有效,因为模式对话框似乎没有处理 WM_QUIT 消息。" 我愿意没有真正得到问题?您要关闭对话框弹出窗口,还是退出应用程序?
  • ...我可以捕获和处理此消息的唯一方法...”哪个消息?
  • 我认为它是 WM_QUIT 消息,当用户单击 Win7 任务栏中的“关闭所有 Windows”按钮时生成的消息。这被模态窗口忽略并阻止应用程序关闭
  • 要深入了解此类问题,windows-message-logger 是首选工具。在 VC 的付费软件版本中,有一个名为 spyXYZ.exe 之类的工具。

标签: c++ c windows event-handling messagebox


【解决方案1】:

模态对话的消息循环应该捕获WM_QUIT 并作为响应调用EndDialog() 并使用PostMessage()WM_QUIT 消息传递到应用程序的主窗口。


更新:

如果将WM_QUIT 发送到模态对话框,上述方法将起作用......但至少在我目前的win7机器上不是这种情况。

此外,主窗口收到一个WM_SYSCOMMAND 并将wParam 设置为SC_CLOSE 并且不知何故默认消息处理程序确实忽略了它(这可能是由于模式对话框的样式...?我没有进一步调查。)。

但是,将以下分支添加到 ma​​in 窗口的消息循环的 switch 应该可以完成在 OP 描述的条件下结束应用程序的工作:

  ...

  case WM_SYSCOMMAND:
    if (SC_CLOSE == wParam)
    {
      PostQuitMessage(<whatever code shall be returned>);
    }

    return DefWindowProc(...);
   
  ...

【讨论】:

  • @GearoidMurphy:不客气。不过,我也为你的其他问题添加了一个简短的答案。
【解决方案2】:

这可能是一个棘手的问题。

通常,要退出 Windows 应用程序,您必须退出“Windows 消息循环”。最简单的方法是发布退出消息,例如PostQuitMessage(retCode),其中 retCode 是您的主消息循环处理程序可以处理的值。通常为零,即忽略。

通常,PostQuitMessage 发布以响应 WM_DESTROY 消息。

这真的取决于遗留代码,你有我的同情,我也在处理遗留代码。我的代码有一个单独的消息循环并不断显示模式对话框。调用 EndDialog 并调用 PostQuitMessage(0) 正确终止了我的应用程序。

【讨论】:

  • 确实,这是一个棘手的问题。如果对可行的解决方案感兴趣,请参阅我对此的回答。
猜你喜欢
  • 1970-01-01
  • 2011-02-24
  • 2011-12-28
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
相关资源
最近更新 更多