您的位置:首页 > 其它

MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕

2007-12-20 15:12 537 查看
引言:
众所周知,微软的MFC Application Framework建立在一系列先进的程序设计技术上的。比如:消息映射机制,命令传递机制,执行期类型识别与动态创建技术及文档序列化技术等。其中执行期类型识别与动态创建技术是其中最重要的技术之一。微软在MFC中用一些神秘的宏实现了这种机制,但是对于学习MFC程序设计的初学者来说它却成为了一大难点,所以在这篇文章中我将详细地为大家挖掘其中的内幕。

正文:
MFC执行期类型识别与动态创建技术是借助CRuntimeClass结构和一系列神秘的宏实现的。而动态创建技术 的前提是执行期类型识别网的建立。下面就让我们来看看执行期类型识别网是如何建立起来的?
///////////////////////////////////////////////////
/*一. 1.CRuntimeClass结构总览 */
///////////////////////////////////////////////////
注释:CRuntimeClass结构定义在../Visual Studio.NET/vc7/atlmfc/include/Afx.h中
// object type information
struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif
// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

// dynamic name lookup and creation
static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);//for ANSI
static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);//for Unicode
static CObject* PASCAL CreateObject(LPCSTR lpszClassName); for ANSI
static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);//for Unicode
// Implementation
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes
const AFX_CLASSINIT* m_pClassInit;
};

/////////////////////////////////////////////////////////
/* 一.2.执行期类型识别网组成部分 */
//////////////////////////////////////////////////////////
在CRuntimeClass结构中与执行期类型识别网建立有关的成员如下:
struct CRuntimeClass
{
...//
LPCSTR m_lpszClassName;
CRuntimeClass* m_pBaseClass;

}

//////////////////////////////////////////////////////////
/*一.3.执行期类型识别网的连接建立*/
//////////////////////////////////////////////////////////
MFC在每一个具有执行期类型识别能力的类的.h和.cpp文件中都添加了两个宏。他们是:
//in xx.h
class class_name
{
DECLARE_DYNAMIC(class_name)
...//
}
//in xx.cpp
IMPLEMENT_DYNAMIC(class_name, base_class_name)
...//
这两个宏展开后是什么样子呢?让我们看看其源代码吧!
注释:这两个宏定义在../Visual Studio.NET/vc7/atlmfc/include/Afx.h中

#define DECLARE_DYNAMIC(class_name) /
public: /
static const CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /

#define IMPLEMENT_DYNAMIC(class_name, base_class_name) /
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)

#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) /
AFX_COMDAT const CRuntimeClass class_name::class##class_name = { /
#class_name, sizeof(class class_name), wSchema, pfnNew, /
RUNTIME_CLASS(base_class_name), NULL, class_init }; /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return RUNTIME_CLASS(class_name); } /
相关宏定义如下:
#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))

看清了吧!这两个宏互相配合着在每个类中都塞进了点东东,至于什么东东,自己看呗儿!

下面我以一个具体的类来展示以下执行期类型识别网是如何连接建立的。
以一个MDI应用程序的CMainFrame类为例:
//in MaimFrm.h
class CMainFrame : public CMDIFrameWnd
{
DECLARE_DYNAMIC(CMainFrame)
...//
}

//in MaimFrm.cpp
IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
...//

我自已架设了博客,文章已转到个人博客,欢迎交流!

MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
http://www.jeanva.cn/post/51.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: