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

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

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

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

提前致谢!

【问题讨论】:

    标签: winapi mfc


    【解决方案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 中有详细记录。
    猜你喜欢
    • 2014-04-05
    • 2011-12-10
    • 1970-01-01
    • 2015-10-15
    • 2021-05-18
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多