现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC六大关键技术分析总结

2012-08-25 23:18 工业·编程 ⁄ 共 2400字 ⁄ 字号 暂无评论

1. MFC初始化的过程

通过全局变量theApp对象(为CMyWinApp类型)创建CMyFrameWnd完成建立窗口。可惜的是仿真中没有delete CMyFrameWnd对象。应该通过虚析构函数delete对象。

2.RTTI功能

为了能够达到RTTI,设计一个CRunTimeClass用于保存一些信息(类名、基类信息、函数指针-动态创建对象使用、模式等)。

设计两类宏,一类宏是在类的声明中使用,主要是给类增加一些成员(数据成员和成员函数)。为RTTI,主要增加一个静态的CRunTimeClass数据成员和一个虚成员函数(GetRunTimeClass),如:

#define DECLARE_DYNAMIC(class_name) /

public: /

static CRuntimeClass class##class_name; /

virtual CRuntimeClass* GetRuntimeClass() const;

第二类宏就是为上面增加的声明增加定义。如:

#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL) /

static char _lpsz##class_name[] = #class_name;/

CRunTimeClass class_name::class##class_name = { /

_lpsz##class_name,sizeof(class_name), wSchema, pfnNew, /

RUNTIME_CLASS(base_class_name), NULL }; /

//注:为了把各个类穿起来,使用下面的宏建立链表

static AFX_CLASSINIT _init_##class_name (&class_name::class##class_name); /

CRuntimeClass* class_name::GetRuntimeClass() const /

{ return &class_name::class##class_name; }

那么我们就可以在根据链表中CRunTimeClass进行RTTI识别了。

3.动态创建

刚才的CRunTimeClass里面有一个函数指针,而且CRunTimeClass对象为静态,因此修改原来的宏为原来类的定义中增加一个静态的CreateObject成员函数,并且在实现宏中让该静态函数和函数指针关联起来。静态的CreatObject成员函数可以new出一个对象并返回,那么我们根据遍历整个CRunTimeClass对象链表,调用对象的函数指针达到动态创建对象。

同样,遗憾的是仿真中没有处理delete动态创建的对象。

4.永久保存(Persistence

这里的永久保存是站在Application Framework的角度来说的。即保存一些数据,框架通过读这些数据能够自动把原本的对象重构出来。

这里也是通过两类宏实现的。这两类宏分别是在类中增加operator>>友元函数(把数据串行化到文件中)的声明和定义。

5.消息映射

同样是通过宏的操作完成。主要是把消息和处理程序关联起来。定义如下:

enum AfxSig

{

AfxSig_end = 0, // [marks end of message map]

AfxSig_vv,

};

struct AFX_MSGMAP

{

AFX_MSGMAP* pBaseMessageMap;

AFX_MSGMAP_ENTRY* lpEntries;

};

增加的声明

#define DECLARE_MESSAGE_MAP() /

static AFX_MSGMAP_ENTRY _messageEntries[]; /

static AFX_MSGMAP messageMap; /

virtual AFX_MSGMAP* GetMessageMap() const;

增加的定义

#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[] = /

{

//这个只是一个仿真,MFC是把处理消息的函数邦定。

#define ON_COMMAND(id, memberFxn) /

{WM_COMMAND, 0, (Word)id, (Word)id,AfxSig_vv, (AFX_MSG)memberFxn }

#define END_MESSAGE_MAP() /

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

};

那么只需要在处理消息的类中使用宏定义就可以了。

6.消息传递

在MFC的消息不仅仅是在派生类和基类之间流动,还可以在同一层次之间流动。如。对于WM_COMMAND来说,消息处理的顺序可以整理为:Frame窗口先接受到消息,依次判断View、Frame窗口本身、CWinApp的DefWndProc是否处理,如果View要处理消息他也会依次判断View本身处理还是Document处理,如果是Document处理他也会依次判断Document本事处理还是Document Template处理。

因为上面类的层次关系。对于消息的传递只能通过静态、全局函数/虚函数来完成。

MFC的初始化和消息传递是需要OS支持的,并不需要用户干预,所以这些内容大多不会以宏来定义。剩下的四个专题都会和用户的具体需求相关,因此要求用户通过简单的宏完成代码的添加。

给我留言

留言无头像?