GetMessage和PeekMessage的區別


 
在Win32中使用GetMessage和PeekMessage都可以獲取對應該程序產生的消息。
他們有什麼區別呢?
GetMessage的一般用法是GetMessage(&msg,NULL,0,0);
這樣可以接受所有的消息,GetMessage在沒有產生消息的時候並不返回,
而是一直在等待,直到一個消息返回;
當消息不是WM_QUIT時,返回一個非零值,也就是說,當是WM_QUIT時會返回一個零。
如果你在使用中如下使用:
While(true)
{
if(GetMessage(&msg,NULL,0,0))
    break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}


則會出現問題,什麼問題呢,就是你結束程序時,窗口是結束了。
但是你去任務管理器裏看,還能看到那個進程。
所以正確的用法應是:
While(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}




PeekMessage不管有沒有消息都會返回一個值,有消息是非零值,沒有消息則是零值。
所以如果上面代碼用PeekMessage的話就不會出現這樣的問題了。
在使用PeekMessage的時候需要指定對消息的處理方法,一般使用PM_REMOVE,即刪除消息。
PeekMessage(&msg,NULL,0,0,PM_REMOVE);
使用這個函數一個問題是他會一直佔用你的CPU,因爲一般情況下我們會一直讓他循環,
而這個函數就會一直不停的取消息。


當然這兩個函數各有各的好處,PeekMessage可以在沒有輸入消息的時候也處理一些事情。




關於這個兩個函數的詳細信息:
BOOL GetMessage(
  LPMSG lpMsg,         // 一個MSG的指針
  HWND hWnd,           // 一般爲當前窗口的句柄
  UINT wMsgFilterMin,  // 要取的消息的最小值
  UINT wMsgFilterMax   // 要取的消息的最大值
);


如果第三,四個參數都爲零,則取所有的消息。
如果出現錯誤,比如參數一或參數而指向的指針或句柄無效,則會返回-1.


BOOL PeekMessage(
  LPMSG lpMsg,        
  HWND hWnd,          
  UINT wMsgFilterMin, 
  UINT wMsgFilterMax,   //前四個參數和GetMessage的一樣
  UINT wRemoveMsg      // 取完消息要做的操作
);


最後一個參數有PM_NOREMOVE和PM_REMOVE兩種方式,前一種就是取完消息後不刪除消息,
不知道這中方式在什麼情況下會採用,我目前還沒有見過。
一般都是採用後一種刪除的方法。


兩個函數主要有以下兩個區別:


    1.GetMessage將等到有合適的消息時才返回,而PeekMessage只是撇一下消息隊列。


    2.GetMessage會將消息從隊列中刪除,而PeekMessage可以設置最後一個參數wRemoveMsg來決定是否將消息保留在隊列中。


      在Windows的內部,GetMessage和PeekMessage執行着相同的代碼。而兩者最大的不同之處則體現在沒有任何消息返回到應用程序的情況下。在此種情況下,PeekMessage會返回一個空值到應用程序,GetMessage會在此時讓應用程序休眠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章