CMDIChildWnd* pActiveChild = MDIGetActive();
CDocument* pDocument = pActiveChild->GetActiveDocument();
CView* pVew = pActiveChild->GetActiveView();
CDocTemplate* pTemplate = pDocument->GetDocTemplate();
CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, pActiveChild);
pTemplate->InitialUpdateFrame(pFrame, pDocument);
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MyEditorTYPE,
RUNTIME_CLASS(CMyEditorDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMyEditorView));
MSDN曰:对于MFC中每个从CObject派生的类来说,都有一个相关的CRuntimeClass结构体,在程序运行时可以访问该结构体来获取对象及其基类的信息。
CRuntimeClass是一个结构体,并且其本身并没有基类。
在运行时确定一个对象的类型是很重要的,尤其是在做类型检查时;而c++语言本身并不支持运行时类信息。
CObject和CRuntimeClass是MFC中两个非常重要的类/结构,绝大部分MFC类都是以CObject做为基类, CRuntimeClass结构同CObject密不可分,了解它们对于深入理解MFC具有重要意义。
CRuntimeClass 的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
struct
CRuntimeClass
{
// Attributes
LPCSTR
m_lpszClassName;
//类名,一般是指包含CRuntimeClass对象的类的名称
int
m_nObjectSize;
//包含CRuntimeClass对象的类sizeof的大小,不包括它分配的内存
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;
//m_pBaseClass的指针(函数)是MFC运行时确定类层次的关键,它一个简单的单向链表
#endif
// Operations
//这个函数给予CObject 派生类运行时动态建立的能力
CObject* CreateObject();
//这个函数使用 m_pBaseClass或 m_pfnGetBaseClass遍历整个类层次确定是否pBaseClass指向的类是基类,
//使用它可以判断某类是否是从pBaseClass指向的类在派生来。
BOOL
IsDerivedFrom(
const
CRuntimeClass* pBaseClass)
const
;
// Implementation
void
Store(CArchive& ar)
const
;
static
CRuntimeClass* PASCAL Load(CArchive& ar,
UINT
* pwSchemaNum);
// 单向链表,每个类的CRuntimeClass结构体对象的 m_pNextClass 都指向其直接基类的CRuntimeClass结构体对象
// 这一点可以在IMPLEMENT_RUNTIMECLASS 宏定义中看到
CRuntimeClass* m_pNextClass;
// linked list of registered classes
};
|
二、CObject类
CObject是MFC类的大多数类的基类,主要是通过它实现:
(1)、运行类信息;(2)、序列化;(3)、对象诊断输出;(4)、同集合类相兼容;
(1)、运行时类信息:
注意:要想使用CRuntimeClass结构得到运行时类信息,你必须在你的类中包括DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC、 DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE或DECLARE_SERIAL/IMPLEMENT_SERIAL。但你的类必须是从CObject派生的才能使用这些宏, 因为通过DECLARE_DYNAMIC将定义一个实现如下的函数:
CRuntimeClass* PASCAL B::_GetBaseClass()
{
return RUNTIME_CLASS(base_name);
}
其中的RUNTIME_CLASS是这样定义的