VC++中PostMessage、SendMessage和PeekMessage之間的區別


1, PostMessage只把消息放入隊列,不管其他程序是否處理都返回,然后繼續執行,這是個異步消息投放函數。而SendMessage必須等待其他程序處理消息完了之后才返回,繼續執行,這是個同步消息投放函數。而且,PostMessage的返回值表示PostMessage函數執行是否正確;而SendMessage的返回值表示其他程序處理消息后的返回值。這點大家應該都明白。

2, 如果在同一個線程內,PostMessage發送消息時,消息要先放入線程的消息隊列,然后通過消息循環Dispatch到目標窗口。SendMessage發送消息時,系統直接調用目標窗口的消息處理程序,並將結果返回。SendMessage在同一線程中發送消息並不入線程消息隊列。 如果在不同線程內。最好用PostThreadMessage代替PostMessage,他工作的很好。SendMessage發送消息到目標窗口所屬的線程的消息隊列,然后發送消息的線程等待(事實上,他應該還在做一些監測工作,比如監視QS_SENDMESSAGE標志),直到目標窗口處理完並且結果返回,發送消息的線程才繼續運行。這是SendMessage的一般情況,事實上,處理過程要復雜的多。比如,當發送消息的線程監測到有別的窗口SendMessage一個消息到來時,他直接調用窗口處理過程(重入),並將處理結果返回(這個過程不需要消息循環中GetMessage等的支持)。

3, msdn: If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters can not include pointers. Otherwise, the operation will fail.

如果發送的消息碼在WM_USER之下(非自定義消息)且消息參數中帶有指針,那么PostMessage,SendNotifyMessage,SendMessageCallback這些異步消息發送函數將會調用失敗。 最好不要用PostMessage發送帶有指針參數的消息。

 

 

 

 

PostThreadMessage

  函數功能:該函數將一個消息放入(寄送)到指定線程的消息隊列里,不等待線程處理消息就返回。
  函數原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM IParam);
  參數
  idThread:其消息將被寄送的線程的線程標識符。如果線程沒有消息隊列,此函數將失敗。當線程第一次調用一個Win 32 USER或GDI函數時,系統創建線程的消息隊列。要得到更多的信息,參見備注。
  Msg:指定將被寄送的消息的類型。
  wParam:指定附加的消息特定信息。
  IParam:指定附加的消息特定信息。
  返回值:如果函數調用成功,返回非零值。如果函數調用失敗,返回值是零。若想獲得更多的錯誤信息,請調用GetLastError函數。如果idThread不是一個有效的線程標識符或由idThread確定的線程沒有消息隊
  列,GetLastError返回ERROR_INVALID_THREAD。
  備注:消息將寄送到的線程必須創建消息隊列,否則調用PostThreadMessage會失敗。用下列方法之一來處理這種情況:
  調用PostThreadMessage。如果失敗,調用Sleep,再調用PostThreadMessage,反復執行,直到PostThreadMessage成功。
  創建一個事件對象,再創建線程。在調用PostThreadMessage之前,用函數WaitForSingleObject來等特事件被設置為被告知狀態。消息將寄送到的線程調用PeekMessage(£msg,NULL,WM_USER,WM_USER,PM_NOREMOVE)來強制系統創建消息隊列。設置事件,表示線程已准備好接收寄送的消息。
  消息將寄送到的線程通過調用GetMesssge或PeekMesssge來取得消息。返回的MSG結構中的hwnd成員為NULL。

 

PeekMessage

  函數功能:該函數為一個消息檢查線程消息隊列,並將該消息(如果存在)放於指定的結構。
  函數原型:BOOL PeekMessage(LPMSG IpMsg,HWND hWnd,UINT wMSGfilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
  參數:
  lpMsg:接收消息信息的MSG結構指針。
  hWnd:其消息被檢查的窗口的句柄。
  wMsgFilterMin:指定被檢查的消息范圍里的第一個消息。
  wMsgFilterMax:指定被檢查的消息范圍里的最后一個消息。
  wRemoveMsg:確定消息如何被處理。此參數可取下列值之一:
  PM_NOREMOVE:PeekMessage處理后,消息不從隊列里除掉。
  PM_REMOVE:PeekMessage處理后,消息從隊列里除掉。
  可將PM_NOYIELD隨意組合到PM_NOREMOVE或PM_REMOVE。此標志使系統不釋放等待調用程序空閑的線程。
  缺省地,處理所有類型的消息。若只處理某些消息,指定一個或多個下列值:
  PM_QS_INPUT:Windows NT5.0和Windows 98:處理鼠標和鍵盤消息。
  PM_QS_PAINT:Windows NT 5.0和Windows 98:處理畫圖消息。
  PM_QS_POSTMESSAGE:Windows NT 5.0和Windows 98:處理所有被寄送的消息,包括計時器和熱鍵。
  PM_QS_SENDMESSAGE:Windows NT 5.0和Windows 98:處理所有發送消息。
  返回值:如果消息可得到,返回非零值;如果沒有消息可得到,返回值是零。
  備注:和函數GetMessage不一樣的是,函數PeekMesssge在返回前不等待消息被放到隊列里。
  PeekMesssge只得到那些與參數hWnd標識的窗口相聯系的消息或被lsChild確定為其子窗口相聯系的消息,並且該消息要在由參數wMsgFiterMin和wMsgFiherMax確定的范圍內。如果hWnd為NULL,則PeekMessage接收屬於當前調用線程的窗口的消息(PeekMessage不接收屬於其他線程的窗口的消息)。如果hWnd為C1,PeekMessage只返回hWnd值為NULL的消息,該消息由函數PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都為零,GetMessage返回所有可得的消息(即,無范圍過濾)。
  常數WM_KEYFIRST和WMKEYLAST可作為過濾值取得所有鍵盤消息;常數WM_MOUSEFIRST和WM_MOUSELAST可用來接收所有的鼠標消息。
  PeekMessage通常不從隊列里清除WM_PAINT消息。該消息將保留在隊列里直到處理完畢。但如果WM_PAINT消息有一個空更新區,PeekMessage將從隊列里清除WM_PAINT消息。
  Windows CE:有一個NULL更新區的WM_PAINT消息不從隊列里清除。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM