[英]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.