简体   繁体   English

为什么 msg.message 在我的程序中不等于 WM_QUIT

[英]Why doesn't msg.message ever equal WM_QUIT in my program

I have a program that uses peekmessage instead of get message and it is supposed to break if msg.message ever equals WM_QUIT but it never equals and my program never ends.我有一个使用 peekmessage 而不是 get message 的程序,如果msg.message永远等于WM_QUIT ,它应该会中断,但它永远不等于并且我的程序永远不会结束。

    MSG msg = { };
    while (TRUE)
    {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if (msg.message == WM_QUIT) {
            break;
        }
        if (screen == TITLESCREEN) {
            drawTitleScreen();
        }

        if (screen == GAMESCREEN) {
            drawGameScreen();
        }
    }
    return 0;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
        {
            destroyRecorces();
            PostQuitMessage(0);
            return 0;
        }
        case WM_SIZE:
        {
            if (pRenderTarget != NULL)
            {
                GetClientRect(hwnd, &rc);

                D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
                pRenderTarget->Resize(size);

            }
            return 0;
        }
        case WM_GETMINMAXINFO:
        {
            LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
            lpMMI->ptMinTrackSize.x = 300;
            lpMMI->ptMinTrackSize.y = 300;
            return 0;
        }
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

when the window closes postQuitMessage();当窗口关闭postQuitMessage(); is supposed to send a WM_QUIT message but msg.message never equals WM_QUIT应该发送WM_QUIT消息,但msg.message永远不等于WM_QUIT

Unlike GetMessage() , which returns 0 when WM_QUIT is retrieved, PeekMessage() simply returns TRUE when any message is retrieved, and FALSE otherwise.与在检索WM_QUIT时返回0 GetMessage()不同, PeekMessage()在检索到任何消息时仅返回TRUE ,否则返回FALSE You have to check the MSG only when PeekMessage() returns TRUE .只有当PeekMessage()返回TRUE时,您才必须检查MSG There is no guarantee that the MSG is updated when PeekMessage() returns FALSE .无法保证在PeekMessage()返回FALSE时更新MSG But you are checking the MSG only after PeekMessage() returns FALSE .但是您只有在PeekMessage()返回FALSE之后才检查MSG

You need to check the MSG inside of your inner while() loop, as that is the only place that the MSG is guaranteed to contain valid data, eg:您需要检查MSG你内心里面while()循环,因为这就是唯一的地方MSG保证包含有效的数据,例如:

MSG msg;
while (true)
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT) {
            return 0;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if (screen == TITLESCREEN) {
        drawTitleScreen();
    }

    if (screen == GAMESCREEN) {
        drawGameScreen();
    }
}
return 0;

Alternatively:或者:

MSG msg = { };
bool keepLooping = true;
do
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT)
        {
            keepLooping = false;
            break;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if (!keepLooping) {
        break;
    }

    if (screen == TITLESCREEN) {
        drawTitleScreen();
    }

    if (screen == GAMESCREEN) {
        drawGameScreen();
    }
}
while (true);
return 0;

Whether or not msg.message will ever be WM_QUIT where you test for it is not deterministic. msg.message是否永远是 WM_QUIT 您测试它的地方是不确定的。

You are looping on the return value of PeekMessage.您正在循环 PeekMessage 的返回值。 The return value of PeekMessage is true if a message was available.如果消息可用,则 PeekMessage 的返回值为 true。 More than one message may be in the message queue and in such a case this loop will field all of the messages.消息队列中可能有多个消息,在这种情况下,此循环将字段所有消息。 Thus, for the WM_QUIT check to fire there would need to be a WM_QUIT message in the queue and it would need to be the last message in the queue before PeekMessage returns false.因此,要触发 WM_QUIT 检查,队列中需要有 WM_QUIT 消息,并且它需要是 PeekMessage 返回 false 之前队列中的最后一条消息。 This may happen sometimes but you can't count on it happening all the time.这有时可能会发生,但您不能指望它一直发生。

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

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