PostMessage&SendMessage的區別

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發送帶有指針參數的消息。

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Aoouch/archive/2007/03/09/1525457.aspx

在調試程序的時候發現,用PostMessage 傳出去的值在我使用的時候已經發生了變化,百思不得其解。

用循環去找一個文件,找到的文件名稱暫存在一個臨時變量裏面,找到之後把這個名稱傳到另外的函數處理,調試發現,處理的總是在我需要的文件後面找到的文件,原因是在我使用的時候那個暫存變量裏面的值已經發生了變化(循環已經處理到了下一步了),

PostMessage 和SendMessage的區別主要在於是否等待其他程序消息處理。PostMessage只是把消息放入隊列,不管其他程序是否處理都返回,然後繼續執行;而SendMessage必須等待其他程序處理消息後才返回,繼續執行。這兩個函數的返回值也不同,PostMessage的返回值表示PostMessage函數執行是否正確,而SendMessage的返回值表示其他程序處理消息後的返回值。

使用SendMessage()可以解決這個問題,只不過在時間效率上會有點下降。

函數原型:

   LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

   BOOL       PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

LRESULT 返回消息被處理的結果,在消息被處理之後纔會返回。BOOL 只是返回傳送的結果,是不是已經送到消息隊列。

從網絡上找到一些資料:

   

1      PostMessage 是異步的,SendMessage 是同步的。

         PostMessage 只把消息放到隊列,不管消息是不是被處理就返回,消息可能不被處理;

         SendMessage等待消息被處理完了才返回,如果消息不被處理,發送消息的線程將一直處於阻塞狀態,等待消息的返回。

2         同一個線程內:

            SendMessage 發送消息時,由USER32.DLL模塊調用目標窗口的消息處理程序,並將結果返回,SendMessage 在同一個線程裏面發送消息不進入線程消息隊列;PostMessage 發送的消息要先放到消息隊列,然後通過消息循環分派到目標窗口(DispatchMessage)。

3         不同線程:

            SendMessage 發送消息到目標窗口的消息隊列,然後發送消息的線程在USER32。DLL模塊內監視和等待消息的處理結果,直到目標窗口的才處理返回,SendMessage在返回之前還需要做許多工作,如響應別的線程向它發送的SendMessage().PostMessge() 到別的線程的時候最好使用PostThreadMessage  代替。PostMessage()的HWND 參數可以爲NULL,相當於PostThreadMessage() + GetCrrentThreadId.

4         系統處理消息。

            系統只處理(marshal)系統消息(0--WM_USER),發送用戶消息(用戶自己定義)時需要用戶自己處理。

            使用PostMessage,SendNotifyMessage,SendMessageCallback等異步函數發送系統消息時,參數不可以使用指針,因爲發送者不等待消息的處理就返回,接收者還沒有處理,指針就有可能被釋放了,或則內容變化了。

5 在Windows 2000/XP,每個消息隊列最多隻能存放一定數量的消息,超過的將不會被處理就丟掉。系統默認是10000;:[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit

可以修改(我的系統下沒有發現)。

在控制別的應用程序的時候,經常需要等待直到某個功能結束,例如:

   打開一個窗口-->等待直到窗口結束 ,這個時候就可以用到SendMessage

   如果在打開這個窗口後仍然需要對該窗口的界面進行設置,比如Edit的value等等,比如:

      打開一個窗口-->控制窗口的control的屬性

   這個時候就需要PostMessage

使用一個鉤子程序截獲消息後,使用SendMessage把消息發送到主處理程序進行處理,但是在主處理程序還沒有完成任務的時候,被設置鉤子的程序進入了停止的狀態,不可以處理 WM_PAINT, WM_MOVE, .......等的基本信息, 必須要等SendMessage發送出的消息完成後,才能繼續運行,整個界面一片空白,把鉤子消息設置成PostMessage的發送消息形式後,問題解決!

      PostMessage只是把消息放入隊列,不管其他程序是否處理都返回,然後繼續執行;

   而SendMessage必須等待其他程序處理消息後才返回,繼續執行。

      PostMessage的返回值表示PostMessage函數執行是否正確;

   而SendMessage的返回值表示其他程序處理消息後的返回值。 

   使用這兩個發送消息函數的最重要的是要看你的程序是否要對消息的滯後性關注否,PostMessage會造成消息的滯後性,而SendMessage則不會,

消息中儘量要傳值,避免傳遞指針

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