2014-10-10 87 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