【问题标题】:How can I detect window destruction from the main thread?如何从主线程检测窗口破坏?
【发布时间】:2011-02-19 20:51:02
【问题描述】:

通常,“主”窗口类的窗口过程会调用 PostQuitMessage 以响应 WM_DESTROY 消息。

我希望主线程根据它创建的窗口的生命周期来决定何时终止。这样,我选择作为主窗口的任何窗口类都可以有一个没有 PostQuitMessage 的通用窗口过程。

while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);

    if(msg.hwnd == hWnd && msg.message == WM_DESTROY)
    {
        PostQuitMessage(0);
    }
}

以上是我的尝试,但 WM_DESTROY 消息从未发布到消息队列中,它似乎是窗口过程的内部。

有没有办法做到这一点?

【问题讨论】:

    标签: windows winapi


    【解决方案1】:

    WM_DESTROY发送而不是发布,这就是它永远不会进入消息队列的原因。如果它最终出现在WndProc 中,并且没有通过消息泵出现,还有什么其他解释?

    通过调用DestroyWindow 来销毁窗口句柄,然后将WM_DESTROY 消息直接发送到WndProc

    我认为你需要为你的潜在主窗口找到其他方法来决定哪一个是在它被破坏时拉下窗帘的那个。

    【讨论】:

    • 这个解释对你理解问题有帮助吗?
    • 我认为您的意思是 DestroyWindow() 而不是 DestroyWindowHandle()
    • 我真的很想了解“其他方式”是什么。但你的回答值得一票。
    • @martin 我没听懂。如果不了解更多有关您使用的语言、库等的信息,将会很难。无论如何,您的问题是具体是否有办法在消息泵中实现决策,我解释了为什么这是不可能的。
    • @David Hefferman:消息泵示例只是为了阻止“到目前为止你有什么”cmets。标题是从主线程检测窗口破坏(特别是没有在WindowProc中使用PostQuitMessage)。
    【解决方案2】:

    我找到了一种似乎可以做我想做的事情的方法。我受到 Valik 的 http://www.autoitscript.com/forum/topic/66508-peekmessage-and-wm-close/ 的启发来研究子类化。

    首先,我将我想要的窗口的窗口过程替换为一个特殊的“PostQuitMessage”过程。

    Original_WindowProc = (WNDPROC)GetWindowLongPtr(hWnd, GWL_WNDPROC);
    SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)&WindowProc);
    

    窗口过程如下所示:

    LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg,  WPARAM wParam,  LPARAM lParam)
    {
        if(uMsg == WM_DESTROY)
        {
            PostQuitMessage(0);
        }
    
        return CallWindowProc(Original_WindowProc, hWnd, uMsg, wParam, lParam);
    }
    

    这允许我将任何窗口类(包括系统类)转换为我的应用程序的主窗口。

    【讨论】:

    • @Cody 我建议使用SetWindowSubclass 和它的朋友来做你的子类化。
    • @David:可能是一个更好的主意。关于子类化的更一般的文章是here,它涵盖了所有技术及其优缺点。关于SetWindowSubclass 的最大警告是它没有记录并且(我相信)仅在 XP 之前的 Windows 版本中以数字形式导出。我记得从我的 VB 6 天开始就成功使用它,但你的里程可能会有所不同。
    猜你喜欢
    • 2018-03-06
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多