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消息不從隊列里清除。