消息处理(四)

一、线程消息

      在窗体应用中,线程可调用窗口过程处理属于他创建的某个窗口的消息(投递而来),此外还可以直接处理其他线程投递的消息。

(1)定义线程消息标志

      线程消息可以是任意的,不必为WM_USER,当然为了获得系统范围内唯一的消息标志,也可以使用自定义的登记消息作为线程消息

      UINT MYTHREADMSG = RegisterWindowMessage("MYTHREADMSG");

提示:不用static关键字修饰MYTHREADMSG 变量,使得其他CPP文件中可以使用该变量。

(2)手工修改CWindThread的消息映射表,添加线程消息映射宏

     跟线程消息相关的映射宏有两个: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:

二、跨进程处理消息

      进程是操作系统分配资源的基本单位。每个进程都有一个独立的地址空间,并至少拥有一个线程来执行其代码。事实上,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:

原文地址:https://www.cnblogs.com/chengtulang/p/3196414.html