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: