PostMessage與SendMessage的區別

PostMessage將消息放入消息隊列中,不等待消息處理,當即返回,消息隊列裏的消息經過調用GetMessage和PeekMessage取得。異步

函數原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
參數
  hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含義的兩個值:
    HWND_BROADCAST:消息被寄送到系統的全部頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口。消息不被寄送到子窗口。
    NULL:此函數的操做和調用參數dwThread設置爲當前線程的標識符PostThreadMessage函數同樣。
  Msg:指定被寄送的消息。
  wParam:指定附加的消息特定的信息。
  IParam:指定附加的消息特定的信息。
返回值:若是函數調用成功,返回非零值:若是函數調用失敗,返回值是零。若想得到更多的錯誤信息,請調用GetLastError函數。
備註:須要以 HWND_BROADCAST方式通訊的應用程序應當用函數 RegisterwindwosMessage來得到應用程序間通訊的獨特的消息。
  若是發送一個低於WM_USER範圍的消息給異步消息函數(PostMessage.SendNotifyMessage,SendMesssgeCallback),消息參數不能包含指針。不然,操做將會失敗。函數將再接收線程處理消息以前返回,發送者將在內存被使用以前釋放。函數

  PostMessage消息中傳值儘可能避免傳指針,由於消息投遞到目標線程消息隊列後,程序繼續執行,而此時消息並無立刻處理,等到線程處理此消息時,指針內容可能已經釋放,或者發生改變。spa

 

SendMessage發送消息,等到消息被處理後返回,即消息處理函數返回後,SendMessage纔會繼續執行下去;線程

函數原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
參數:
  hWnd:其窗口程序將接收消息的窗口的句柄。若是此參數爲HWND_BROADCAST,則消息將被髮送到系統中全部頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口,但消息不被髮送到子窗口。
  Msg:指定被髮送的消息。
  wParam:指定附加的消息指定信息。
  IParam:指定附加的消息指定信息。
返回值:返回值指定消息處理的結果,依賴於所發送的消息,即消息處理函數返回值。
備註:須要用HWND_BROADCAST通訊的應用程序應當使用函數RegisterWindowMessage來爲應用程序間的通訊取得一個惟一的消息。
  若是指定的窗口是由調用線程建立的,則窗口程序當即做爲子程序調用。若是指定的窗口是由不一樣線程建立的,則系統切換到該線程並調用恰當的窗口程序。線程間的消息只有在線程執行消息檢索代碼時才被處理。發送線程被阻塞直到接收線程處理完消息爲止。指針

 

SendMessageTimeout等待一段時間以後,消息處理函數沒有返回,則放棄等待,繼續執行;隊列

 

PostThreadMessage:將一個消息放入(寄送)到指定線程的消息隊列裏,不等待線程處理消息就返回。內存

BOOL PostThreadMessage (DWORD idThread,   UINT Msg,   WPARAM wParam,   LPARAM IParam);
原型

idThread:
其消息將被寄送的線程的線程標識符。若是線程沒有消息隊列,此函數將失敗。
當線程第一次調用一個Win 32 USER或GDI函數時,系統建立線程的消息隊列。要獲得更多的信息,參見備註。消息隊列

Msg:指定將被寄送的消息的類型。ast

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。
 
返回值:
若是函數調用成功,返回非零值。
若是函數調用失敗,返回值是零。
 
若想得到更多的錯誤信息,請調用GetLastError函數。
若是idThread不是一個有效的線程標識符或由idThread肯定的線程沒有消息隊列,
GetLastError返回ERROR_INVALID_THREAD_ID。
 
備註:消息將寄送到的線程必須建立消息隊列,不然調用PostThreadMessage會失敗。
 

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

相關文章
相關標籤/搜索