长时间人容易遗忘,从新捡起!特做下记录

MFC消息映射

1.在MFC中消息映射主要牵扯到三个宏分别为:

DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(theClass, baseClass)
END_MESSAGE_MAP()

2.先看源码

#define DECLARE_MESSAGE_MAP() \
protected: \
static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return GetThisMessageMap(); } \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
#define END_MESSAGE_MAP() \
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return &messageMap; \
}

3.上述源码中牵扯到两个结构体分别为

struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT_PTR nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};
struct AFX_MSGMAP
{
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
const AFX_MSGMAP_ENTRY* lpEntries;
};

包含两部分:1.函数指针(指向父类的获取AFX_MSGMAP的指针的静态函数)  2.AFX_MSGMAP_ENTRY结构体的指针

形成结构图

4.无论MFC中消息的走向如何(是向基类直接走还是横向走消息),我们先必须把整个爬行路线网建立起来,即如上图就可以把基类和派生类连接起来。

作为消息基类CCmdTarget需要特殊处理,即CCmdTarget的父类的AFX_MSGMAP为NULL,CCmdTarget内的AFX_MSGMAP_ENTRY仅包含一项,       如下:

CCmdTarget类头文件包含

DECLARE_MESSAGE_MAP()

CCmdTarget类源文件有

const AFX_MSGMAP* CCmdTarget::GetMessageMap() const
{
return GetThisMessageMap();
} const AFX_MSGMAP* CCmdTarget::GetThisMessageMap()
{
static const AFX_MSGMAP_ENTRY _messageEntries[] =
{
{ 0, 0, AfxSig_end, 0 } // nothing here
};
static const AFX_MSGMAP messageMap =
{
NULL,
&_messageEntries[0]
};
return &messageMap;
}

简化版本:

#ifndef __DEFINE_H__
#define __DEFINE_H__ typedef void (*CALL_MSG)(int wParam, int lParam); struct MSG_MAP_ENTRY
{
unsigned int nMessage; //消息类型
unsigned int nSig; // 信号类型
CALL_MSG pfn; //回调函数,即处理函数
}; struct MSG_MAP
{
MSG_MAP* (*pfnGetBaseMap)();
MSG_MAP_ENTRY* lpEntries;
}; #define DECLARE_MESSAGE_MAP() \
static const MSG_MAP* GetThisMessageMap(); \
virtual const MSG_MAP* GetMessageMap(); #define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const MSG_MAP* theClass::GetMessageMap(){ \
return GetThisMessageMap(); \
} \
const MSG_MAP* theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const MSG_MAP_ENTRY _messageEntries[] = \
{ #define END_MESSAGE_MAP() \
{0, 0, (CALL_MSG)0 } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return &messageMap; \
} #endif

复习总结《一》MFC消息映射的更多相关文章

  1. MFC消息映射机制以及画线功能实现

    ---此仅供用于学习交流,切勿用于商业用途,转载请注明http://www.cnblogs.com/mxbs/p/6213404.html. 利用VS2010创建一个单文档标准MFC工程,工程名为Dr ...

  2. MFC编程入门之五(MFC消息映射机制概述)

    在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作.比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应. 一.什 ...

  3. VS2010/MFC编程入门之五(MFC消息映射机制概述)

    VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...

  4. MFC消息映射机制

    1.MFC应用框架主要类之间的关系 MFC自动生成的框架中重要的类有:C-App.CMainFrame.C-Doc和C-View. 其他的类如CClassView.CFileView等都是在框架窗口( ...

  5. MFC消息映射与命令传递

    题外话:刚开始学视窗程序设计的时候,我就打印了一本Windows消息详解,里面列举了各种已定义消息的意义和作用,共10多页,在编程的时候翻翻,有时觉得很受用.我发觉很多编程的朋友,虽然每天都面对消息, ...

  6. MFC技术内幕系列之(四)---MFC消息映射与消息传递内幕

    ////////////////////////////////////////////////////////////////////////////////////                 ...

  7. MFC消息映射的原理:笔记

    多态的实现机制有两种,一是通过查找绝对位置表,二是查找名称表:两者各有优缺点,那么为什么mfc的消息映射采用了第二种方法,而不是c++使用的第一种呢?因为在mfc的gui类库是一个庞大的继承体系,而里 ...

  8. MFC 消息映射表和虚函数实现消息映射到底谁的效率高

    深入浅出MFC对于虚函数实现方式的缺点,它指出:虚函数耗费大量内存,系统最终将被这些额外负担拖垮. 但是现在对于容量巨大的白菜价格的内存来说,这种额外负担是否已经过时了呢~?    书中提到,虚函数表 ...

  9. 深入浅出MFC——消息映射与命令传递(六)

    1. 消息分类: 2. 万流归宗——Command Target(CCmdTarget): 3. "消息映射"是MFC内建的一个信息分派机制.通过三个宏(DECLARE_MESSA ...

随机推荐

  1. JavaScript 闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包-无处不在  在前端编程中,使 ...

  2. 下载Google Play外国区APP技巧

    安卓用户若遇到喜欢的APP是外国区的,只要FQ就能下载.比起果粉还要注册,是简便很多.但有没有更简单的办法?这个必须有!笔者前几天在网上闲逛时,就发现了一个给力的网站.让你不用FQ,只需3个步骤,就能 ...

  3. C# 拆箱与装箱及优化

    1.概念 装箱在值类型向引用类型转换时发生,在堆中分配. 拆箱在引用类型向值类型转换时发生. 2.装箱拆箱的过程 //这行语句将整型常量1赋给object类型的变量obj:众所周知常量1是值类型,值类 ...

  4. C# AES 加密与解密

    AES 算法加密(ECB模式) 将明文加密,加密后进行base64编码,返回密文 /// <summary> /// AES 算法加密(ECB模式) 将明文加密,加密后进行base64编码 ...

  5. 学会阅读Java字节码

    1.Class文件基础   (1)文件格式     Class文件的结构不像XML等描述语言那样松散自由.由于它没有任何分隔符号, 所以,以上数据项无论是顺序还是数量都是被严格限定的.哪个字节代表什么 ...

  6. 用logstash,elasticSearch,kibana实现数据收集和统计分析工作

    原文链接:http://www.open-open.com/lib/view/open1448799635720.html 世界上的软件80%是运行在内网的,为了使得运行在客户端的软件有良好的体验,并 ...

  7. 【CF819D】Mister B and Astronomers EXGCD

    [CF819D]Mister B and Astronomers 题意:小鼠Jack想当太空人(哦不,太空鼠)!为此,它在夜晚带领一堆小朋友一起来到户外看星星.一共有 $n​$ 只小鼠,这些小鼠围成一 ...

  8. iOS - Charles抓包数据

    一.Charles Charles破解版下载地址点我 1.1 Charles主要的功能 .截取Http.Https网络请求内容 .支持修改网络请求参数,方便调试 .支持网络请求的截取 并动态修改 1. ...

  9. ssh连接超时时间(ssh timeout)的设置方法

    问题:当某台远程主机宕机时,ssh远程过去会耗费很多的时间去连接,结果还是会失败. 这个时候可以设置超时时间 ssh -o ConnectTimeout= 192.168.0.10

  10. AD初体验

    首先是因为想用51做个小项目,所以想到不如成这个机会把AD学一下吧,老师说我们这个专业无论画图还是电路设计都得精通,想想自己还是能力欠缺,到大三了才开始学习绘制 原理图. 好了废话不说,下面说说我的第 ...