关于c ++:WM_CLOSE事件从不发送/接收?

the WM_CLOSE event is never sent/received?

我正在学习DX12,并在此过程中学习"旧版Win32"。
我在退出主循环时遇到问题,这似乎与我没有收到WM_CLOSE消息有关。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#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!\
"
;

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

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

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

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

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

    std::cout <<"Entering main loop\
"
;
    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\
"
;
                ::PostQuitMessage(0);
                break;
            }
            continue;
        }

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

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

    return 0;
}

当我按下红色的X(关闭)窗口按钮时,窗口关闭,但:

  • 未打印"已关闭"
  • 不显示"离开主循环"。

输出为:

1
2
3
4
5
6
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之间,应该有一个事件与关闭窗口有关,不是吗?

我是这个的初学者。 我试图搜索google和stackoverflow,但是我不知道上下文是否适用于我,或者它太具体/不相关。 它可能是重复的,但我找不到。

我可能正在丢失/跳过消息吗? 这就是我能想到的。


多亏了Simon Mourier的评论和指向教程的链接,问题才得以解决。

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

我要重新发布经过修改,清理,工作的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#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\
"
;
        ::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;
}