我想知道这两个片段之间是否存在差异:
void main()
{
// ...
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ExitProcess(0);
}
// ...
void quit()
{
PostQuitMessage(0);
}
bool quit = false;
void main()
{
// ...
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(quit)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&_msg);
}
ExitProcess(0);
}
}
// Shouldn't get here
ExitProcess(1);
}
// ...
void quit()
{
quit = true;
PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
}
很抱歉,但我无法提出更短的代码段。
我的问题是,调用PostQuitMessage
并使用GetMessage
处理所有邮件是否等同于处理PeekMessage
的所有邮件,直到它返回FALSE
。
According to Raymond,WM_QUIT
仅在消息队列为空时生成",所以看起来两种方法应该相同,但可能在那里"一个微妙的区别。
答案 0 :(得分:6)
因为系统尝试不在"坏的情况下注入WM_QUIT消息 时间&#34 ;;相反,它等待着#34;安定下来"在生成之前 WM_QUIT消息,从而减少了程序的机会 可能正处于由a触发的多步骤过程中 发布的消息序列。
所以理论上没有,没有区别,因为系统在队列为空之前不会生成WM_QUIT
。然而,雷蒙德并没有说它是保证消息在WM_QUIT
生成后不会到达,只是系统尝试避免它。
因此,可以想象,在您退出主GetMessage
循环后,另一个主题可能会向您发送消息,并且根据您的应用,这可能是您必须处理的内容。例如,如果您在内部发布带有内存分配的消息,接收线程应该是空闲的,那么在线程完全退出之前,您可能需要一个单独的PeekMessage
循环来清理它们。
在实践中,没有人像你的第二个例子那样编写消息循环。
答案 1 :(得分:1)
我认为接受的答案没有解决真正的问题。
雷蒙德直接here回答了这个问题。
基本上:
您无法控制每个消息循环,因此您没有那个选项。
哦,顺便说一句,别忘了PostQuitMessage
在你自己的消息循环中。
请注意,even WTL neglects to do this!
它依赖于你将CMessageLoop::Run
的返回值传递给PostQuitMessage
。