2014-10-10 92 views
1

我不知道是否有这两个片段之间的差异:使用PostQuitMessage和仅处理所有消息有什么不同?

一:

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); 
} 

很抱歉,但我不能想出更短的片段。

我的问题的关键在于是否调用PostQuitMessageGetMessage处理所有消息等效于PeekMessage处理所有消息,直到它返回FALSE

According to Raymond,WM_QUIT是“仅当消息队列为空时才生成”,所以它看起来像两个方法应该做同样的事情,但也许有一个细微的差别。

+2

这是纯粹的知识分子的好奇心还是你试图用你的非标准方法来达到特定的效果? – 2014-10-10 23:34:30

+0

@AdrianMcCarthy我正在查看一个使用某种非标准编程风格的人的代码库。除此之外,除非确实需要,否则他不愿意更改代码。所以我想知道他所做的至少是正确的。 – Paul 2014-10-11 09:16:48

回答

6

雷蒙德的博客文章说:

由于系统试图不是在一个“坏 时间”注入WM_QUIT消息;相反,它会在生成WM_QUIT消息之前等待事情“安顿下来”,从而减少程序 可能处于由发布的消息序列触发的多步骤过程的中间的可能性。

所以理论上没有区别,因为在队列为空之前系统不会生成WM_QUIT。然而雷蒙德并没有说它的保证消息将不会到达WM_QUIT生成后,只有系统尝试以避免它。

因此,在您退出主要GetMessage循环后,另一个线程可能会向您发送消息,根据您的应用程序,这可能是您必须处理的事情。例如,如果您使用内存分配在内部发布消息,并希望接收线程可以释放,则可能需要单独的一个PeekMessage循环在线程完全退出之前将其清除。

实际上,没有人会像第二个例子那样编写消息循环。

+0

谢谢。我明白,在这两个例子中,一个消息可以在循环退出后发布,并且没有什么可以做的,但我认为可能特殊的'WM_QUIT'做了一些不能手动完成的事情。附:第二个例子是我在代码库中看到的,这就是为什么我问这个问题。 – Paul 2014-10-11 09:27:06