简体   繁体   English

单独的窗口消息泵和接收WM_QUIT

[英]Separate window message pumps and receiving WM_QUIT

I'm trying to create independent window wrapper classes for my project. 我正在尝试为我的项目创建独立的窗口包装器类。 It's mostly working but cannot figure out how to get WM_QUIT in my main message pump. 它通常可以正常工作,但无法弄清楚如何在我的主消息泵中获取WM_QUIT。 In the interest of learning Windows, I don't want to use other libraries for this. 为了学习Windows,我不想为此使用其他库。

This is a quick example of whats happening. 这是一个正在发生的事的快速示例。

#include <iostream>
#include <Windows.h>

void TestPump()
{
    MSG msg = { 0 };

    PostQuitMessage(0);
    std::cout << "Posted WM_QUIT" << std::endl;

    while (true)
    {
        BOOL result = PeekMessage(&msg, (HWND) -1, 0, 0, PM_REMOVE);

        std::cout << "PeekMessage returned " << result << std::endl;

        if (result == 0)
            break;

        if (WM_QUIT == msg.message)
            std::cout << "got WM_QUIT" << std::endl;
    }
}

void MakeWindow()
{
    auto hwnd = CreateWindowEx(0, "Button", "dummy", 0, 0, 0, 32, 32, NULL, NULL, NULL, NULL);
    std::cout << std::endl << "Created Window" << std::endl << std::endl;
}

int main()
{
    TestPump();
    MakeWindow();
    TestPump();

    std::cin.get();

    return EXIT_SUCCESS;
}

The PeekMessage documentation is here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644943(v=vs.85).aspx PeekMessage文档位于此处: https ://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644943( v= vs.85).aspx

I haven't been able to find any examples of using a -1 HWND filter, but MSDN says that it'll receive thread messages where the HWND is NULL (I've checked that this is true for WM_QUIT), which I believe PostQuitMessage does with WM_QUIT. 我还没有找到使用-1 HWND过滤器的任何示例,但是MSDN说它将接收HWND为NULL的线程消息(我检查过WM_QUIT的确如此),我相信PostQuitMessage与WM_QUIT有关。

The problem only occurs if I create a Window. 仅当我创建一个窗口时才会出现此问题。

Is there anything I'm doing wrong, or are there better methods? 我做错了什么吗,还是有更好的方法?

This seems to be an interesting case so I've created a mcve, though I'm struggling to explain this behavior: 这似乎是一个有趣的案例,所以我创建了一个mcve,尽管我正在努力解释这种行为:

#include <Windows.h>
#include <CommCtrl.h>

#include <iostream>
#include <cassert>

void
Create_ThreadMessagePump(void)
{
    ::MSG msg;
    ::PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
    ::std::wcout << L"initialized thread message pump" << ::std::endl;
}

void
Create_Window(void)
{
    auto const hwnd{::CreateWindowExW(0, WC_STATICW, L"dummy window", 0, 0, 0, 32, 32, NULL, NULL, NULL, NULL)};
    (void) hwnd; // not used
    assert(NULL != hwnd);
    ::std::wcout << L"created window" << ::std::endl;
}

void
Test_QuitMessageExtraction(void)
{
    ::PostQuitMessage(0);
    ::std::wcout << L"posted WM_QUIT" << ::std::endl;
    for(;;)
    {   
        ::MSG msg;
        auto const result{::PeekMessageW(&msg, (HWND) -1, 0, 0, PM_REMOVE)};
        ::std::wcout << L"PeekMessageW returned " << result << ::std::endl;
        if(0 == result)
        {
            ::std::wcout << L"no more messages to peek" << ::std::endl;
            break;
        }
        if(WM_QUIT == msg.message)
        {
            ::std::wcout << L"got WM_QUIT" << ::std::endl;
        }
    }
}

int
main()
{
    //Create_ThreadMessagePump(); // does not change anything
    Test_QuitMessageExtraction();
    Create_Window();
    Test_QuitMessageExtraction();
    system("pause");
    return(0);
}

output: 输出:

posted WM_QUIT
PeekMessageW returned 1
got WM_QUIT
PeekMessageW returned 0
no more messages to peek
created window
posted WM_QUIT
PeekMessageW returned 0
no more messages to peek

The problem appears to be with the way WM_QUIT and PostQuitMessage() operates. 问题似乎与WM_QUITPostQuitMessage()操作方式有关。 You can find information here: 您可以在此处找到信息:

Why is there a special PostQuitMessage function? 为什么会有特殊的PostQuitMessage函数? .

In short, the WM_QUIT message will not be received while the queue is non-empty. 简而言之,当队列为非空时,将不会收到WM_QUIT消息。 Even if you filter out other messages by using a -1 HWND , the queue is still non-empty, and thus WM_QUIT is not returned. 即使使用-1 HWND过滤掉其他消息,该队列仍然是非空的,因此不会返回WM_QUIT Creating of a window results in multiple HWNDs being created. 创建窗口会导致创建多个HWND。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM