1、線程消息函數
在窗體應用中,線程可調用窗口過程處理屬於他建立的某個窗口的消息(投遞而來),此外還能夠直接處理其餘線程投遞的消息。spa
(1)定義線程消息標誌操作系統
線程消息能夠是任意的,沒必要爲WM_USER,固然爲了得到系統範圍內惟一的消息標誌,也能夠使用自定義的登記消息做爲線程消息線程
UINT MYTHREADMSG = RegisterWindowMessage("MYTHREADMSG");code
提示:不用static關鍵字修飾MYTHREADMSG 變量,使得其餘CPP文件中能夠使用該變量。對象
(2)手工修改CWindThread的消息映射表,添加線程消息映射宏blog
跟線程消息相關的映射宏有兩個:ON_THREAD_MESSAGE和ON_REGISTERED_THREAD_MESSAGE。前者處理通常的線程消息,然後者專用於處理登記的線程消息。隊列
#define ON_THREAD_MESSAGE(message,memberFxn)\ {message,0,0,0,AfxSig_vwl,\ (AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL CWinThread::*)(WPARAM,LPARAM)>(memberFxn))},
#define ON_REGISTERED_THREAD_MESSAGE(message,memberFxn)\ {message,0,0,0,(UINT_PTR)(UINT *)(&nMessageVariable),\ (AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL CWinThread::*)(WPARAM,LPARAM)>(memberFxn))},
從上面的定義能夠看出:進程
a.只有CWinThread類才容許處理線程消息。資源
b.線程消息處理函數的簽名形式爲:void (WPARAM,LPARAM)
(3)實現處理線程消息的成員
void (WPARAM,LPARAM)
(4)引起線程消息。
經過調用CWinThread對象的PostThreadMessage,將線程消息投遞到CWinThread對象的線程隊列。
Example:
2、跨進程處理消息
進程是操做系統分配資源的基本單位。每一個進程都有一個獨立的地址空間,並至少擁有一個線程來執行其代碼。事實上,Windows提供的消息處理機制是徹底能夠跨進程進行的。雖然每一個進程都在獨立的地址空間中運行,可是各個進程都共享一段系統分區(又稱核心區),核心區將被映射到每一個進程空間中,而且其位置也是固定的。操做系統在覈心區放置了一些關鍵數據(這些數據又稱核心對象),並提供了一組API函數對這些數據進行操做。而這些核心區剛好就保存了系統當前建立的全部窗口,並將每一個窗口和建立它的線程關聯起來。
由於由核心區的數據提供的信息,系統能夠定位到任何一個窗口,從窗口出發,系統還能夠找到建立該窗口的線程,而後就能夠輕易的把消息放入線程的消息隊列中。
(1)定位到接收消息的窗口
爲了找到接收消息的窗口,能夠調用FindWindow,依據窗口的類名和窗口名(也就是窗口標題)查找特定的窗口:
HWND FindWindow( LPCTSTR lpClassName, //窗口類名 LPCTSTR lpWindowName //窗口名,也就是窗口標題 );
能夠將lpClassName或lpWindowName設爲NULL,這時將忽略窗口類名或窗口名,僅依據一個條件進行搜索。這種方法最多隻能返回一個窗口。
若是要支持查找多個窗口,能夠用EnumWindow函數:
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, //回調函數 LPARAM lParam //回調函數的參數 );
每當找到一個窗口,系統就會執行lpEnumFunc,其原型定義爲:BOOL CALLBACK (HWND hWnd, LPARAM lParam)
參數hWnd表示當前正在枚舉的窗口,lParam是由調用EnumWindows時的第二參數lParam規定的,若是但願繼續枚舉窗口,則返回TRUE,不然返回FALSE。在回調函數內,能夠依據必定的條件判斷hWnd窗口是否爲目標窗口,如果,則能夠向其發送消息。
提示:對於表明窗口的窗口句柄,其值在系統範圍都是惟一的,這也簡化了跨進程的消息通訊的實現。
(2)向窗口發送消息
找到目標窗口後,就能夠用SendMessage或PostMessage向其發送或投遞消息。
(3)目標窗口響應消息
消息映射宏:ON_REGISTERED_MESSAGE
成員函數的簽名:LRESULT (WPARAM,LPARAM)
Example: