消息映射-学习总结

消息映射和命令传递是紧密相连的两部分。就像运行时类型识别和动态创建,后者都要在前者搭建的框架上执行。在消息映射和命令传递中,消息映射表的创建是基础,命令的传递路线是核心,让我跟随书中的足迹,记下自己学习中的心得。

 

 

消息映射(Message Mapping)的关键,是建立起一张消息攀爬的线路网,即消息映射表(Message Map)。以这张表为基础,将消息与表格中的元素比较,然后调用相应的处理程序,这种操作就是消息映射。

 

 

如果把消息映射表比作人体,我们可以大抵把它分成两部分,一部分是构成身体的骨骼,另一部分则是血肉。骨骼搭成框架,血肉使其生动,富有变化。消息映射表也是如此。整个表格就包含两个数据结构:AFX_MSGMAPAFX_MSGMAP_ENTRY。其中,AFX_MSGMAP相当于骨骼,它构成了映射表的框架;AFX_MSGMAP_ENTRY好比血肉,依附于AFX_MSGMAP,构成整个映射表的元素内容。下面,让我们来认识一下这两个结构体:

 

struct  AFX_MSGMAP

{

AFX_MSGMAP* pBaseMessageMap;

AFX_MSGMAP_ENTRY* lpEntries;

};

 

 

 

看到这里,我想大家就明白了,AFX_MSGMAP之所以能够搭成框架,是由于其中的成员是两个指针,它们各有各的用途。其中,AFX_MSGMAP_ENTRY就是我们要认识的第二个数据结构:

Struct  AFX_MSGMAP_ENTRY

{

UINT nMessage;

UINT nCode;

UINT nID;

UINT nLastID;

UINT nSig;

AFX_PMSG pfn;

}

 

 

它记录了消息的内容和参数,作为比较的依据。

 

于是,每一个与消息相关的类中,都会存在这两个数据结构的对象。当然,它们必须是静态类型(static),以表明只属于类本身。如何把它们放到类中,就要依靠宏的本领了。引用侯捷先生的话,“他们并没有改变C++语言本身,也没有扩大语言的功能。他们只是设计了一些令人拍案叫绝的宏,而这些宏背后隐藏着巨大的机制”。这里体现出的,才刚刚开始,让我们见识一下吧。定义一个宏:

 

#define  DECLARE_MESSAGE_MAP()

static AFX_MSGMAP_ENTRY _messageEntries[ ];

static AFX_MSGMAP messageMap;

virtual AFX_MSGMAP* GetMessageMap() const;

 

 

 

它们作为类的静态成员,就成为了所属类在消息映射表中的全权代表。于是,我们只需要在定义与消息有关的类时,把此宏放到类中,就OK了。代表有了,还有初始化的任务。

这两个数据结构的内容填塞工作又由三个宏完成:

 

 

#define BEGIN_MESSAGE_MAP(theClass, baseClass)

AFX_MSGMAP*  theClass::GetMessageMap() const

{ return &theClass::messageMap;}

AFX_MSGMAP  theClass::messageMap = 

{ &(baseClass::messageMap),

(AFX_MSGMAP_ENTRY*) &(theClass::_messageEntries)};

AFX_MSGMAP_ENTRY  theClass::_messageEntries[ ] = 

{

#define ON_COMMAND(id, memberFxn)

{ WM_COMMAND, 0, (WORD)id, (WORD)id, 

AfxSig_vv, (AFX_PMSG)memberFxn},

#define END_MESSAGE_MAP()

{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0}

};

 

 

 

这里的关键是ON_COMMAND宏。因为对这个宏作用的理解还不透彻,所以只引用侯捷先生的话,“我们还可以定义各种类似ON_COMMAND这样的宏,把各式各样的消息与特定的处理程序关联起来”。理解不够透彻,是指透过这个宏,自己难以把消息本身和它对应处理程序的联系搞清楚。当再次遇到功能类似的宏时,再来比对学习。

 

到这里,消息映射表的搭建与填充工作就告一段落了。每个与消息有关的类,都已由其代表AFX_MSGMAPAFX_MSGMAP_ENTRY组成的元素在映射表中占据一席之地。各种不同的消息,如何在表中游走,与表中元素进行对比并调用对应的处理程序,这就是下篇 Command Routing中的内容。虽然框架已经搭好,但真正的好戏还在后头呢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值