为什么 msg.message 在我的程序中不等于 WM_QUIT
Why doesn't msg.message ever equal WM_QUIT in my program
我有一个使用 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);
}
当 window 关闭时 postQuitMessage(); 应该发送 WM_QUIT
消息,但 msg.message
永远不会等于 WM_QUIT
msg.message
是否会WM_QUIT 你测试它的地方是不确定的。
您正在循环查看 PeekMessage 的 return 值。如果消息可用,则 PeekMessage 的 return 值为真。消息队列中可能有不止一条消息,在这种情况下,此循环将处理所有消息。因此,要触发 WM_QUIT 检查,队列中需要 WM_QUIT 消息 并且 它需要是之前队列中的最后一条消息PeekMessage return 为假。有时可能会发生这种情况,但您不能指望它一直发生。
与 GetMessage()
不同,returns 0
当 WM_QUIT
被检索时,PeekMessage()
只是 returns TRUE
当 任何消息被检索,FALSE
否则。只有在 PeekMessage()
returns TRUE
时才需要检查 MSG
。无法保证 MSG
在 PeekMessage()
returns FALSE
时更新。但是您仅在 PeekMessage()
returns FALSE
.
之后检查 MSG
您需要检查内部 while()
循环中的 MSG
,因为这是唯一保证 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;
或者:
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;
我有一个使用 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);
}
当 window 关闭时 postQuitMessage(); 应该发送 WM_QUIT
消息,但 msg.message
永远不会等于 WM_QUIT
msg.message
是否会WM_QUIT 你测试它的地方是不确定的。
您正在循环查看 PeekMessage 的 return 值。如果消息可用,则 PeekMessage 的 return 值为真。消息队列中可能有不止一条消息,在这种情况下,此循环将处理所有消息。因此,要触发 WM_QUIT 检查,队列中需要 WM_QUIT 消息 并且 它需要是之前队列中的最后一条消息PeekMessage return 为假。有时可能会发生这种情况,但您不能指望它一直发生。
与 GetMessage()
不同,returns 0
当 WM_QUIT
被检索时,PeekMessage()
只是 returns TRUE
当 任何消息被检索,FALSE
否则。只有在 PeekMessage()
returns TRUE
时才需要检查 MSG
。无法保证 MSG
在 PeekMessage()
returns FALSE
时更新。但是您仅在 PeekMessage()
returns FALSE
.
MSG
您需要检查内部 while()
循环中的 MSG
,因为这是唯一保证 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;
或者:
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;