Reputation: 106
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.
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(); is supposed to send a WM_QUIT
message but msg.message
never equals WM_QUIT
Upvotes: 0
Views: 1133
Reputation: 595369
Unlike GetMessage()
, which returns 0
when WM_QUIT
is retrieved, PeekMessage()
simply returns TRUE
when any message is retrieved, and FALSE
otherwise. You have to check the MSG
only when PeekMessage()
returns TRUE
. There is no guarantee that the MSG
is updated when PeekMessage()
returns FALSE
. But you are checking the MSG
only after PeekMessage()
returns FALSE
.
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 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;
Upvotes: 3
Reputation: 9525
Whether or not msg.message
will ever be WM_QUIT where you test for it is not deterministic.
You are looping on the return value of PeekMessage. The return value of PeekMessage is true if a message was available. 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. This may happen sometimes but you can't count on it happening all the time.
Upvotes: 1