故障現象1:可以收到SendMessage()發出的消息,但收不到PostMessage()發出的消息。html
故障現象2:可以收到PostMessage()發出的消息,但收不到SendMessage()發出的消息。緩存
從發送端來講:函數
SendMessage()比如電信系統提供通話服務。ui
若是對方佔線,當即返回。spa
若是對方不佔線,就保持呼叫→接收端接聽→通話→掛斷。在掛斷以前,發送端處於阻塞狀態,不能夠幹別的事。操作系統
PostMessage()比如電子郵件系統提供電子郵件服務。orm
發送端把郵件交給電子郵件系統,而後當即返回,就能夠幹別的事了。htm
電子郵件系統將郵件放在隊列緩存區中,緩慢地將郵件發送到接收端的郵箱裏。blog
從接收端來講(!!! 關鍵 關鍵 關鍵 !!!):隊列
要接收SendMessage()的消息,必須用手機接聽,到郵箱裏沒法接收此類消息。
要接收PostMessage()的消息,必須到郵箱裏接收,用手機沒法接聽此類消息。
在本文中:
把SendMessage()發送的消息成爲當即消息。
把PostMessage()發送的消息成爲延遲消息。
在計算機系統裏,當即消息和延遲消息分別使用徹底不一樣的途徑發送消息,必須採用相匹配的、徹底不一樣的接收方法才能收到消息。
爲了接收並處理當即消息,接收端應用程序必須準備一張(消息,處理函數)映射表,以下表所示:
消息 |
處理函數 |
WM_USER + 1 |
OnWmUser_1 |
WM_USER + 2 |
OnWmUser_2 |
… |
… |
WM_USER + n |
OnWmUser_n |
當即消息的發送與接收的協做流程以下表:
發送端應用程序 |
操做系統 |
接收端應用程序 (消息處理總入口函數) |
發送消息 |
|
|
|
阻塞發送端應用程序 |
|
|
調用接收端應用程序的消息處理總入口函數 |
|
|
|
在(消息,處理函數)映射表中搜索與消息相匹配的處理函數,當即調用處理函數。 |
|
|
向操做系統返回處理結果 |
|
向發送端應用程序返回處理結果 |
|
|
解除阻塞發送端應用程序 |
|
接收消息處理結果 |
|
|
繼續其它事務 |
|
|
延遲消息的發送與接收的協做流程以下表:
發送端應用程序 |
操做系統 |
接收端應用程序 |
發送消息 |
|
|
|
將消息放入接收端應用程序的消息隊列中 |
|
繼續其它事務 |
|
從消息隊列中取出消息慢慢處理。 |
以C++ Builder爲例。
要接收當即消息,也就是由SendMessage()發送的消息。
步驟1:聲明並定義消息處理函數
步驟2:聲明和定義(消息,處理函數)映射表
class TForm2 : public TForm { // 聲明WM_COPYDATA 消息的處理函數 void __fastcall OnCopyData(const TMessage &msg);
// 受理當即消息 --- 由 SendMessage() 發送的消息 // 聲明和定義(消息,處理函數)映射表 BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, OnCopyData); END_MESSAGE_MAP(TForm) }; |
要接收延遲消息,也就是由PostMessage()發送的消息。
放置一個TApplicationEvents控件,該控件只能接收延遲消息,沒法接收當即消息。
編寫TApplicationEvents.OnMessage事件處理函數。以下表:
void __fastcall TForm2::AppEventsMessage(tagMSG &Msg, bool &Handled) { // 若收到延遲消息WM_USER_1 if (Msg.message == WM_USER_1) { // 此處編寫消息處理代碼 // 設立標誌,消息已被處理 Handled = true; } else { // 設立標誌,消息未被處理 Handled = false; } } |
SendMessage()和PostMessage()的共性:
都能發送消息。
SendMessage和PostMessage的差別:
採用徹底不一樣的途徑發送消息,也要採用徹底不一樣的方法和途徑接收消息。
若接收途徑與發送途徑不匹配,就沒法接收消息。
經過SendMessage()發送的消息,發送端發送並必須等待接收端處理,接收端當即處理並向發送端反饋處理結果,無延遲。
經過PostMessage()發送的消息,發送端發送後當即返回,不等待接收端不處理,接收端緩慢地延遲處理。
|
SendMessage |
PostMessage() |
發送端 |
直接發給接收端 要求接收端當即處理 在接收端處理完畢以前處於阻塞狀態,不能夠幹別的事 能夠當即獲悉接收端的處理結果 |
消息經由OS緩存到接收端的消息隊列裏 發送完畢當即返回,能夠幹別的事 |
接收端 |
當即處理收到的消息 |
緩慢地從隊列裏取出消息並處理。 |
SendMessage和PostMessage的其它特性,網上都有,本文再也不重複與累述。
原文出處:https://www.cnblogs.com/micemik/p/11576878.html