DECLARE_MESSAGE_MAP()与消息传递网

更新时间:2023-06-08 08:41:18 阅读: 评论:0

DECLARE_MESSAGE_MAP()与消息传递网
一.总体结构
首先,在.h文件中:
    DECLARE_MESSAGE_MAP()
然后在.CPP文件中:
    BEGIN_MESSAGE_MAP(CView, CWnd)
        ON_COMMAND(CViewid, 0)
END_MESSAGE_MAP()
上面.h中的宏的声明是:
#define DECLARE_MESSAGE_MAP\
static AFX_MSGMAP_ENTRY _messageEntries[];\
static AFX_MSGMAP messageMap;\
virtual AFX_MSGMAP*GetMessageMap()const;
该宏相当于在类中声明两个static数据成员和一个虚成员函数。 
它们的定义由.CPP中的三个宏实现:
#define BEGIN_MESSAGE_MAP(class_name,ba_class)\
AFX_MSGMAP*class_name::GetMessageMap()const\
        {return &class_name::message;}\
悯农简笔画
AFX_MSGMAP messageMap=\
        {&ba_class::messageMap,class_name::_messageEntries}\
AFX_MSGMAP_ENTRY _messageEntries[]=\
        {
#define ON_COMMAND(id,memFunc)\
菠萝怎么种植盆栽              {WM_COMMAND,0,id,id,AFx_sig_vv,(AFX_PMSG)memFunc },
#define END_MESSAGE_MAP()\
       {0,0,0,0,AfxSig_end,(AFX_PMSG)0}\
    };
注意这三个宏中的内容共同完成了一个AFX_MSGMAP_ENTRY结构体数组的填写,其花括号上面用红色斜体标了出来。因此这三个宏必须连在一起调用,且前后顺序必须正确
总体来说,就是DECLARE_MESSAGE_MAP负责俩个成员变量与一个成员函数的声明,BEGIN_MESSAGE_MAPON_COMMANDEND_MESSAGE_MAP负责声明所对应的实现。
二.关于声明
至于其中声明的成员变量,如下:
1.  AFX_MSGMAP。该结构体负责存储两个指针,分别指向基类的 AFX_MSGMAP,以及本类的消息映射表AFX_MSGMAP_ENTRY
struct AFX_MSGMAP
{
AFX_MSGMAP *pBaMessageMap;//指向基类的本结构。
AFX_MSGMAP_ENTRY*lpEntries;//本类的消息映射表。
};
2.消息映射表AFX_MSGMAP_ENTRY。该结构体可以存储一条消息的所有相关信息。在类中,使用了该结构体类型的数组,因此本类有多少消息,就需要在数组中存多少元素。
struct AFX_MSGMAP_ENTRY
{
秋葵怎么切UINT nMessage;
UINT nCode;
UINT nID;
UINT nLastID;
UINT nSig;
AFX_PMSG pfn;
};
该结构体最后的成员AFX_PMSG也是个结构体,其声明如下:
3.函数指针
typedef void (CCmdTarget::*AFX_PMSG)(void); 
很明显,AFX_PMSG指向的函数指针是相应消息的处理函数。当触发某个消息时,就会调用该消息所对应的函数指针。
以上声明,展开就是:
Class CView:public CWnd
{
Public:
    ……
static AFX_MSGMAP_ENTRY  _messageEntries[];\海外市场营销
static AFX_MSGMAP  messageMap;\
virtual唱一首好歌 AFX_MSGMAP* GetMessageMap()const;
};
三.关于实现
.CPP中的三个宏,负责对.h声明的两个成员变量与一个成员函数进行实现。展开后:
AFX_MSGMAP*class_name::GetMessageMap()const
      {喜帖街歌词背后的意思
return &class_name::message;
}
AFX_MSGMAP messageMap=
{    &ba_class::messageMap,class_name::_messageEntries
}
AFX_MSGMAP_ENTRY _messageEntries[]=
{   
    {WM_COMMAND,0,id,id,AFx_sig_vv,(AFX_PMSG)memFunc },
{0,0,0,0,AfxSig_end,(AFX_PMSG)0}
    };
可见,本类中主要的数据成员只有一个,就是消息映射表AFX_MSGMAP_ENTRY数组。
AFX_MSGMAP的两个成员变量,一个指向基类AFX_MSGMAP_ENTRY,一个指向本类的AFX_MSGMAP_ENTRY
而那个成员函数GetMessageMap()则是用来获取本类的AFX_MSGMAP的。
因此,若有派生关系:CCmdeTarget->CWnd->CView->CMyView
则:
可以通过GetMessageMap()用来获取CMyViewAFX_MSGMAP,从而得到CMyView剖腹藏珠的AFX_MSGMAP_ENTRY和基类的AFX_MSGMAP (也就是CViewAFX_MSGMAP) 。
中国制造英语
由于得到了CViewAFX_MSGMAP,于是又有了CViewAFX_MSGMAP_ENTRY和基类的AFX_MSGMAP (也就是CWndAFX_MSGMAP) 。
同理,可以获取CCmdeTargetAFX_MSGMAP。但CCmdeTarget就是最终消息的源头类了,不会再上溯。因此CCmdeTargetAFX_MSGMAP需要单独实现。
故而,一条消息,交给一个派生类对象CMyView后,可以不断上溯,直到到达CCmdeTarget
这,就是消息传递网。这张网为消息在基类与派生类之间传递提供了通道。但现在仅仅是架设了一张网,消息进来后,还是不能自行传递或流动,缺乏一个推动消息前进的动力。该动力属于Windows程序设计的工作。
特别注意,在这张网中,消息一定是由派生类流向基类的,纵向流动,而不能逆流(基类流向派生类)或者横流(流向兄弟类)对于一般的Windows消息(WM_xxx),一定遵循此规则。
对于命令消息WM_COMMAND,消息流动则可能有其他路线。
夹在BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间的宏,上面是ON_COMMAND。该宏的作用是将消息与消息处理函数绑定。但除了ON_COMMAND之外,还有很多其他的宏也用于这里。比如ON_ WM_CREATEON_WM_LBUTTONDOWNON_WM_PAINT等。
不同之处在于,ON_COMMAND宏可以将很多不同类型的消息与处理函数绑定,而不局限于某个固定的消息。但如ON_WM_CREATE宏,则只用于将WM_CREATE消息与消息处理函数OnCreate绑定。
所以,对于每个非WM_COMMAND的Windows标准消息,也就是WM_xxx,都有一个已经定义好的宏ON_ WM_xxx负责该消息跟处理函数的绑定。

本文发布于:2023-06-08 08:41:18,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/901217.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:消息   成员   处理函数   声明   基类   结构   派生类   流动
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图