MFC,如何从主窗口关闭模态对话框?

3
我们有一个名为X的对话框,可以由不同的线程(包括主线程)作为模态打开。同时从不同的线程打开多个模态X对话框是可能的。
我们希望在主窗口处理SC_CLOSE消息时关闭所有X(仅限X)模态对话框。
问题是:如何从主窗口关闭所有模态X对话框,当它接收到SC_CLOSE消息?仅限X!因此,PostQuitMessage无法帮助我们,因为它会关闭整个应用程序,我们不想关闭应用程序,如果其他模态对话框如Y,Z ...已经打开。
信息:当我们从主线程以及其他线程打开模态X对话框时,主窗口可以处理SC_CLOSE消息。并且X没有子模态窗口。

“在进程间,父/子或拥有者/拥有窗口关系是否合法?” “是的,在技术上是合法的。在技术上玩链锯也是合法的。” - IInspectable
@IInspectable 我们的对话框就像一个消息框,所以我们没有真正的管理问题。看起来我的问题很像这个:链接,但我不想关闭 X 对话框。 - Yusuf R. Karagöz
你没有理解问题所在。你正在使用一个模态对话框,其所有者窗口由另一个线程拥有。只有在你特别实现了安全性时,才支持这种情况。由于你正在使用MFC,这是不可能的,因为你无法访问消息分发代码。这已经被嵌入到了MFC的实现中。你所做的不安全,也无法变得安全。 - IInspectable
1
@IInspectable,你说得没错,但总有些事情是我无法改变的: )。我不能再改变设计了。我正在处理一款已经存在20年的软件。直到今天,我们从未因为安全问题出过麻烦。只是看起来不同的线程显示自定义消息框。也许所有的X对话框可以以线程安全的方式在一个静态全局集合中注册,那么我能关闭这些对话框吗? - Yusuf R. Karagöz
当您单击关闭按钮时,发送的消息是WM_CLOSE,而不是SC_CLOSE。您也可以自己发送它。当然,因为您有一个多线程设置,如果您在任何给定点告诉消息框关闭,我不确定会发生什么... - andlabs
你需要拥有相同的数据库来维护这些对话HWND并通过关键段进行保护。对于对话框X,在WM_INITDIALOG中添加它的HWND到此数据库中,在WM_DESTROY中从数据库中删除HWND。当需要全部关闭时,枚举DB中的HWND(s)并为所有设置WM_CLOSE。同时将一些退出标志设置为真-以防某个线程开始创建此对话框X,但尚未在DB中注册自己-当退出标志设置时-仅在WM_INITDIALOG中销毁自身。 - RbMm
1个回答

4

我的当前解决方案是:

在打开所有模态X对话框时,它们已经被注册到一个集合中(线程安全)。如果主窗口成为SC_CLOSE消息,则现在可以迭代所有对话框。然后针对每个对话框使用以下两行之一。

  ::PostMessage(pDlg->GetSafeHwnd(), WM_COMMAND, IDOK, 0); //end dialog with idok
  ::PostMessage(pDlg->GetSafeHwnd(), WM_CLOSE, 0, 0);      //or, close dialog

我知道这不是最好的解决方案,但希望能对某些人有所帮助。

不要尝试迭代主窗口的所有子项来查找对话框,这样做没有帮助。对话框的所有者并不意味着它是对话框的父级。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接