使用 Win32/MFC 关闭并等待子框架窗口的最佳方法

Posted

技术标签:

【中文标题】使用 Win32/MFC 关闭并等待子框架窗口的最佳方法【英文标题】:Best way to close and wait for a child frame window using Win32/MFC 【发布时间】:2009-06-11 13:04:39 【问题描述】:

这里可能有几个选项,但您建议以最安全的方式完成以下操作:

我有一个父级 = NULL 的子级 CFrameWnd(至少在应用程序运行时,它可以与主应用程序分开生活)。我已经将所有这些窗口存储在一个列表中。当主应用程序关闭时(MainFrame 获得 OnClose),我遍历数组并向所有人发出 PostMessage(WM_CLOSE)。然而,问题是他们每个人都必须在关闭之前做一些事情。所以,我需要等他们。但是我们都在同一个线程上......那么,我怎样才能等待孩子关闭,而不阻塞他们自己在单线程应用程序中的处理?

或者我应该启动一个工作线程来解决这个问题?会不会容易些?

提前致谢!

【问题讨论】:

【参考方案1】:

使用 SendMessage() 代替 PostMessage()。

编辑:另一种选择可能是在您的子窗口中简单地处理 WM_DESTROY(当然取决于您的代码)。

【讨论】:

是的,当然... WM_DESTROY 对我来说为时已晚,但我需要的是 SendMessage - 有时显而易见的事情摆在你面前 :) 谢谢。【参考方案2】:

你当然不能只等他们关闭,你至少需要pump messages,这样他们才能接收和处理WM_CLOSE。我猜你如何做到这一点取决于你。但我看到你在做PostMessage。为什么不改用SendMessage - 这将在窗口的窗口过程中同步运行关闭。还是您要退出该应用程序?那么你真的应该使用PostQuitMessage,然后以正常方式发送消息,直到GetMessage 返回0。有很多选择。

Pumping messages 意味着在你的代码中有一个看起来像这样的循环。您不必致电AfxPumpMessages,但这可能会做类似的事情。实际上,根据您想要做什么,有许多不同的方式来发送消息。此外,还有很多功能可以为您发送消息。

BOOL bRet;

// note that GetMessage returns 0 when WM_QUIT is received - this is how PostQuitMessage
// would work to get us to shut down
// We are passing NULL for the hWnd parameter - this means receive all window and
// thread messages for this thread
while( (bRet = GetMessage( &msg, NULL /* hWnd */, 0, 0 )) != 0)
 
    if (bRet == -1)
    
        // handle the error and possibly exit
    
    else
    
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    

如果您将消息发布到一个或多个窗口,那么您需要泵送消息。发生的情况是消息进入与该窗口关联的线程(此线程)的队列 - 消息泵将它们提取出来并将它们分派到正确的窗口过程。

如果您发送消息而不是发布消息,则直接调用窗口的窗口过程 - 而不是进入队列。您不需要发送消息,因为一旦 SendMessage 返回消息已被完全处理。

PostQuitMessageworks 的方式是在消息队列上设置一个标志,指示应用程序应该退出。 WM_QUIT 消息实际上并不是您要发送的窗口消息 - 发生的情况是 GetMessage 将在处理完所有其他已发布的窗口消息后检查此标志,如果已设置则返回 0。这将导致所有窗口正确关闭,您无需将其发送到窗口本身。

【讨论】:

是的,我可以使用 AfxPumpMessage,但这不适用于单个线程。 SendMessage 似乎是最好的方法。是的,我要退出应用程序,PostQuitMessage 是一个好主意——但我不明白如何 PostQuitMessage,然后在 GetMessage 返回 0 时泵送消息——是主窗口中的 GetMessage 吗?它可以在许多其他时间返回 0。不太清楚你的意思。谢谢! 我添加了一些关于消息泵如何工作以及 PostQuitMessage 的秘密行为的更多细节。你真的应该检查一下,因为你似乎对消息处理有一些基本的误解 我了解 Post 和 Send 之间的区别,但感谢代码 sn-p - 它在其他情况下可能会很有用! SendMessage 效果很好,所以我会坚持使用它,除非有理由不这样做。 GetMessage 仅在收到 WM_QUIT 时返回 0,在所有其他情况下它返回 0 以外的值。这在 MSDN msdn.microsoft.com/en-us/library/ms644936(VS.85).aspx 中有详细记录。

以上是关于使用 Win32/MFC 关闭并等待子框架窗口的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5从子窗口关闭父窗口和子窗口

Win32Api -- 关闭当前应用

在无模式对话框中阻止 ESC 和 Enter 键(Win32,非 MFC)

如何在 MFC 自定义控件类中挂钩控件关闭

使用 Win32/MFC 将 HTML 文件转换为 PDF

如何本地化 win32(非 MFC)DLL