WM_CLOSE 事件永远不会是 sent/received?

the WM_CLOSE event is never sent/received?

我正在学习 DX12,并在此过程中学习“优秀的 Win32”。 我无法退出主循环,这似乎与我没有收到 WM_CLOSE 消息有关。

在 C++ 中,Windows10,控制台应用程序。

#include <iostream>
#include <d3d12.h>
#include <dxgi1_4.h>
#include <tchar.h>

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return ::DefWindowProc(hWnd, msg, wParam, lParam);
}


int main()
{
    std::cout << "Hello World!\n";

    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX),
        CS_CLASSDC,
        WndProc,
        0L, 0L,
        GetModuleHandle(NULL),
        NULL, NULL, NULL, NULL,
        _T("ker engine"),
        NULL
    };

    std::cout << "Registering Class\n";
    ::RegisterClassEx(&wc);

    std::cout << "Creating Window\n";
    HWND hwnd = ::CreateWindow(
        wc.lpszClassName,
        _T("Ker Engine DX12"),
        WS_OVERLAPPEDWINDOW,
        100, 100, 1280, 800, NULL, NULL,
        wc.hInstance, NULL
    );

    std::cout << "Show Window\n";
    ::ShowWindow(hwnd, SW_SHOWDEFAULT);

    std::cout << "Update Window\n";
    ::UpdateWindow(hwnd);

    std::cout << "Entering main loop\n";
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    while (msg.message != (WM_QUIT))
    {
        if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
            std::cout << msg.message << std::endl;
            switch (msg.message)
            {
            case WM_CLOSE:
                std::cout << "close received\n";
                ::PostQuitMessage(0);
                break;
            }
            continue;
        }

    }
    std::cout << "leaving main loop\n";

    std::cout << "Destroy Window\n";
    ::DestroyWindow(hwnd);
    std::cout << "Unregister Class\n";
    ::UnregisterClass(wc.lpszClassName, wc.hInstance);
    std::cout << "Bye\n";

    return 0;
}

当我按下 X(关闭)红色 window 按钮时,window 关闭但是:

输出为:

Entering main loop
[a lot of message code, in decimal]
160  (a lot of it) (WM_NCMOUSEMOVE)
161  (WM_NCLBUTTONDOWN)
275  (WM_TIMER)
no more output printed, i have to close the console manually.

没有WM_CLOSE,或WM_DESTROY,或WM_QUIT。在 BUTTONDOW 和 TIMER 应该是什么之间,应该有一个与 windows 已关闭的事实相关的事件,不是吗?

我是这方面的初学者。我尝试搜索 google 和 Whosebug,但我不明白上下文是否适用于我,或者太 specific/unrelated。它可能是重复的,但我找不到它。

我是 losing/skiping 消息吗?我能想到的就这些了。

感谢 Simon Mourier 的评论和 link 教程,问题已解决。

消息处理必须在 WndProc 中完成,而不是在“主循环”中。

我正在重新发布修改后的、清理过的、有效的代码:

#include <iostream>
#include <d3d12.h>
#include <dxgi1_4.h>
#include <tchar.h>

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        std::cout << "close received\n";
        ::PostQuitMessage(0);
        return 0;
    }
    return ::DefWindowProc(hWnd, msg, wParam, lParam);
}


int main()
{
    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX),
        CS_CLASSDC,
        WndProc,
        0L, 0L,
        GetModuleHandle(NULL),
        NULL, NULL, NULL, NULL,
        _T("ker engine"),
        NULL
    };

    ::RegisterClassEx(&wc);

    HWND hwnd = ::CreateWindow(
        wc.lpszClassName,
        _T("Ker Engine DX12"),
        WS_OVERLAPPEDWINDOW,
        100, 100, 1280, 800, NULL, NULL,
        wc.hInstance, NULL
    );

    ::ShowWindow(hwnd, SW_SHOWDEFAULT);
    ::UpdateWindow(hwnd);

    MSG msg;
    ZeroMemory(&msg, sizeof(msg));
    while (msg.message != (WM_QUIT))
    {
        if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }    
    }
    ::DestroyWindow(hwnd);
    ::UnregisterClass(wc.lpszClassName, wc.hInstance);

    return 0;
}