Win32 API訊息函數:SendMessage
函數功能:該函數將指定的訊息發送到一個或多個視窗。此函數為指定的視窗調用視窗程序,直到視窗程 序處理完訊息再返回。而函數PostMessage不同,將一個訊息寄送到一個線程的訊息佇列後立即返回。
函數原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
參數:
hWnd:其視窗程序將接收訊息的視窗的控制代碼。如果此參數為HWND_BROADCAST,則訊息將被發送到系統中所有頂層視窗,包括無效或不可見的非自 身擁有的視窗、被覆蓋的視窗和彈出式視窗,但訊息不被發送到子視窗。
Msg:指定被發送的訊息。
wParam:指定附加的訊息指定資訊。
IParam:指定附加的訊息指定資訊。
傳回值:傳回值指定訊息處理的結果,依賴於所發送的訊息。
備忘:需要用HWND_BROADCAST通訊的應用程式應當使用函數RegisterWindowMessage來為應用程式間的通訊取得一個唯一的消 息。
如果指定的視窗是由調用線程建立的,則視窗程序立即作為子程式調用。如果指定的視窗是由不同線程建立的,則系統切換到該線程並調用恰當的視窗程序。線程間 的訊息只有線上程執行訊息檢索代碼時才被處理。發送線程被阻塞直到接收線程處理完訊息為止。
Windows CE:Windows CE不支援Windows案頭平台支援的所有訊息。使用SendMesssge之前,要檢查發送的訊息是否被支援。
速查:Windows NT:3.1及以上版本:Windows:95及以上版本;Windows CE:1.0及以上版本;標頭檔:winuser.h;輸入庫:user32.lib;Unicode:在Windows NT環境下以Unicode和ANSI方式實現。
Win32 API訊息函數: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),訊息參數不能包含指標。否則,操作將會失 敗。函數將再接收線程處理訊息之前返回,寄件者將在記憶體被使用之前釋放。
速查:Windows NT: 3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;標頭檔:winuser.h;輸入庫:user32.lib;Unicode:在Windows NT環境下以Unicode和ANSI方式實現。
在控制別的應用程式的時候,經常需要等待直到某個功能結束,例如:
開啟一個視窗-->等待直到視窗結束
這 個時候就可以用到SendMessage
如果在開啟這個視窗後仍然需要對該視窗的介面進行設定,比如Edit的value等等,比如:
打 開一個視窗-->控制視窗的control的屬性
這個時候就需要PostMessage
使用一個鉤子程式截獲訊息後,使用 SendMessage把訊息發送到主處理常式進行處理,但是在主處理常式還沒有完成任務的時候,被設定鉤子的程式進入了停止的狀態,不可以處理
WM_PAINT,
WM_MOVE,
....... 等的基本資料,
必須要等SendMessage發送出的訊息完成後,才能繼續運行,整個介面一片空白,把鉤子訊息設定成PostMessage的 發送訊息形式後,問題解決!
我查了MSDN對這兩個API的定義,
PostMessage只是把訊息放入隊列,不管其他程式是否處理都返 回,然後繼續執行;
而SendMessage必須等待其他程式處理訊息後才返回,繼續執行。
PostMessage的傳回值表示 PostMessage函數執行是否正確;
而SendMessage的傳回值表示其他程式處理訊息後的傳回值。
使用這兩個發送訊息函數 的最重要的是要看你的程式是否要對訊息的滯後性關注否,PostMessage會造成訊息的滯後性,而SendMessage則不會,但如果 SendMessage訊息處理失敗,則會造成程式停止!
===============================================
1. SendMessage函數要等到訊息被處理後才返回
PostMessage 訊息發出後馬上返回
2. PostMessage發向目標視窗的訊息一定會進入訊息佇列
SendMessage向同一線程的視窗發訊息,不會進入訊息佇列,
SendMessage向其他線程的視窗發訊息,則會進入訊息佇列,
3. PostMessage的傳回值表示PostMessage函數執行是否正確,
SendMessage的傳回值表示其他程式處理訊息後的傳回值
1、SendMessage()和PostMessage().這兩個函數幾乎是一樣的,它們的區別是:
SendMessage()直接把一個訊息發給視窗過程,等訊息被處理後才返回。Postmessage()只是把訊息發送到訊息佇列,完成後即返回。
2.1、當調用SendMessage時,接收訊息的線程的QS_SENDMESSAGE標誌被設定,系統調用相應的視窗過程來處理這個訊息。 GetMessage和PeekMessage函數在內部進行這種處理。如果在“發送訊息佇列”中沒有訊息了,QS_SENDMESSAGE標誌就被關 閉。“發送訊息佇列”中可能有幾個Send過來的訊息。例如,幾個線程同時向一個視窗發送訊息。
2.2、當調用PostMessage時,函數GetMessage或PeekMessage填充傳遞給它們的Msg結構,函數返回。再調用 DispatchMessage,讓相應的視窗過程來處理訊息。
2.3、當調用SendMessage時,發送線程和接收線程是同一個線程的時候,SendMessag很簡單,只是調用指定視窗的視窗過程。但當 發送線程和接收線程不是同一個線程時,麻煩就大了。因為發送線程和接收線程運行在不同的地址空間中,因此不能訪問接受線程中相應視窗過程的代碼和資料。其 實這時發送線程要掛起,當接收線程處理Send過來的訊息時,發送線程被設定為空白閑(idle)狀態。在發送的訊息處理完成後,視窗過程的傳回值被登記到 發送線程的應答訊息佇列中。發送線程被喚醒,取出包含在應答訊息佇列中的傳回值。這個傳回值就是調用SendMessage的傳回值,這時,發送線程繼續 運行。
2.4、WM_PAINT和WM_TIMER這兩個訊息的優先順序非常低,最低的是WM_TIMER。
2.5、WM_COPYDATA只能Send,不能Post。