消息

1,  什么是消息?

    消息只不过是一个无符号整数,操作系统使用宏预定义了大量的宏。当然程序员自己也可以自己定义消息。

      #define WM_CLOSE_ME   WM_USER+1

但是要确保自己定义的消息不应该与已经有的系统定义的消息不冲突。

可以采用,确保值0x0400(WM_USER)和0x7FFF之间,操作系统已经保留了0x0000 到0x3FF(WM_USER-1)之间的数值,应用程序不能使用。

2,  消息映射表

     CWnd提供的窗口过程通过OnWndMsg,OnCommand和OnNotify等成员的调用,将消息最终分派到各个成员函数来处理,在消息分配的最后一步,要通过一个叫消息映射表的数据结构,来根据消息类型找到合适的成员。消息映射表中包含了各种类型的消息处理函数的入口。MFC中的消息主要有四类。

凡是从CmdTarget派生的类都支持通过消息映射表查找合适的成员函数来处理消息。

为了在CmdTarget派生类中添加消息映射表,只要:

(1)        在类的声明的头文件中加入DECLARE_MESSAGE_MAP()宏。

(2)        在实现文件中加入BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP宏,它们负责初始化消息映射表。BEGIN_MESSAGE_MAP接收两个参数当前的类和基类。为了将具体的消息和消息处理函数关联起来,必须在两个宏之间加入若干消息映射宏。不同类别的类,它们的消息映射宏也不同,具有不同的参数。

消息映射宏中有一大类是处理普通窗口消息的。CWnd类已经将这些消息和其成员函数挂钩起来,注意,一般处理这些消息的成员都没有定义为虚函数,以节省开支。

还有命令消息。以及控件通知消息和通知消息映射宏。

 

3,  消息队列

窗口本身仅提供了处理消息的窗口过程,但窗口本身并不处理消息。真正的处理是由创建窗口的线程来进行的。线程对创建的窗口有拥有权,所以创建窗口的线程必须是为窗口处理所有消息的线程。

    也就是说如果一个线程创建了一个窗口,那么都应该由系统对它分配一个容纳待处理的消息的队列。这个队列用于窗口消息的派送,并且为了使得窗口能接收这些消息,线程必须有自己的消息循环。线程通过消息循环,从消息队列中取出消息,并分派到特定的窗口过程处理该消息,在处理消息的过程中可能又会产生其他消息,这些消息被放到消息队列中。如此不断反复,直到应用程序调用了         PostQuitMessage为止。为了将消息投递到线程的消息队列中,系统首先要依据MSG结构进行过滤,然后将MSG结构拷贝到消息队列中。

    

用程序需要通过调用API函数GetMessage从消息队列中移出一条消息。然后,通过调用DispatchMessage将消息分派到适当的窗口过程进行处理。

3.1   投递和发送消息

  通过向一个窗体投递或者发送消息,可以间接地驱动窗体的消息过程从而执行特定的成员函数。这种方式比直接调用窗口对象的成员函数,具有如下优越性:

(1) 可以依靠线程的消息循环机制自动实现任务排队,从而实现调用的序列化,以保证待执行的成员函数是线程安全的,省去了对线程同步的考虑,简化了程序设计。

(2)可以跨线程,跨进程发送或者投递消息。但是直接对成员函数的调用只能在同一个线程内进行。

      现在说说“跨进程消息处理”------进程是操作系统分配资源的基本单位。每一个进程都有一个独立的地址空间,并至少拥有一个线程(主线程)来执行其代码。通常的应用是假定激发消息的线程和接收消息在同一个进程的情况下进行。事实上,Windows提供的消息处理机制是完全可以跨进程进行的。这听起来有点不可思议----不是说每个进程在独立的地址空间中运行吗?的确如此,但是还要注意各个进程有一个共享一段系统分区-----又称为“核心区”。这个核心区将被映射到每个进程空间中,并且其位置也是固定的。操作系统的核心区放置了一些关键数据(又称为是“核心对象”),操作系统提供了一组API函数对这些数据进行操作。而这些核心区恰好就保存了系统当前创建的所有窗口,并将每个窗口和创建它的线程关联了起来。

      这样跨进程的消息处理就好办了。因为由核心区的数据提供的信息,系统可以定位到任何一个窗口,从窗口出发,系统还可以找到创建该窗口的线程,然后就可以轻易地把消息放到线程的消息队列中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值