【问题标题】:Message loop not exiting when I close the window关闭窗口时消息循环未退出
【发布时间】:2020-12-16 22:27:24
【问题描述】:

我是使用 Win32 API 编程的新手,并且一直试图弄清楚为什么当我关闭窗口时这个应用程序没有返回。

#include <windows.h>

LRESULT CALLBACK WindowProc(
    _In_ HWND   hwnd,
    _In_ UINT   uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
);

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    // Register window class
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = L"Window Class";

    RegisterClass(&wc);

    // Create window
    HWND window = CreateWindowEx(
        0,
        wc.lpszClassName,
        L"Window",
        WS_OVERLAPPEDWINDOW,

        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,
        NULL,
        hInstance,
        NULL
    );

    // Show window
    ShowWindow(window, nShowCmd);

    // Main Program Loop
    MSG msg = {};
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, window, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}

LRESULT CALLBACK WindowProc(
    _In_ HWND   hwnd,
    _In_ UINT   uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

我用调试器单步执行代码,看到销毁窗口后,消息的值为WM_PAINT,所以程序一直在循环,但我不明白为什么WM_QUIT没有已发布。

【问题讨论】:

标签: winapi


【解决方案1】:

通过提供window 作为PeekMessage 的参数,您告诉它您只想检索发布或发送到该窗口的消息。

WM_QUIT 是一个线程消息 - 它与任何给定窗口无关。要检索它,您需要使用nullptr 调用PeekMessage 来获取窗口过滤器。

【讨论】:

【解决方案2】:

除了Jonathan Potter's answer,你的消息循环应该使用GetMessage()而不是PeekMessage()

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

GetMessage() 阻塞调用线程直到消息到达,当收到WM_QUIThWnd 参数为NULL 时返回FALSE

通过使用PeekMessage(),您正在运行一个紧凑的繁忙循环,当PeekMessage() 在没有可用消息时返回 FALSE 时,msg 的内容不确定

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 2018-12-03
    • 1970-01-01
    • 2012-11-05
    相关资源
    最近更新 更多