本次仿真的主要内容有:
- MFC的基本框架
- 在基本框架的基础上添加类别信息网
代码阅读建议:
读者对MFC基本框架了解:
读者只需看类别信息网部分,理解类别信息网的 关键是 一个结构体和 几个宏, 本质上就是通过结构体构建一个类别信息串行(也就是 单链表)。
读者只需看类别信息网部分,理解类别信息网的 关键是 一个结构体和 几个宏, 本质上就是通过结构体构建一个类别信息串行(也就是 单链表)。
读者对MFC基本框架不了解:
建议先看基本框架部分,也就是
忽略一些看不懂的宏,
只
看类的继承关系(参照下图和源代码熟悉每一个类的继承关系),
再看每一个类里的细节部分。代码中仿真了下图中实线框部分的类,也就是只仿真了MFC的基本框架类,而虚线框表示的程序框架部分没有仿真。
如有不懂可下方留言或者参看侯杰的《深入浅出MFC》
声明:本博文代码来源于侯杰的《深入浅出MFC》,如有侵权请与本人联系,本博文的主要目的是为了交流学习,也是分享本人对MFC的一些理解,如有不对的地方还望指正。
代码部分:
mfc.h
/**************************************************************************************
* 文件名 :mfc.h
* 摘要 :mfc框架结构仿真
* 作者 :张群伟
* 日期 :[4/2/2017]
* 历史记录 :
* 修改者: 日期: 版本: 修改内容:
*
**************************************************************************************/
#define BOOL int
#define TRUE 1
#define FALSE 0
#define LPCSTR LPSTR
typedef char* LPSTR;
#define UINT int
#define PASCAL _stdcall
#include <iostream>
//++ 构建类别信息网
/**************************************************************************************
* 结构体名 :CRuntimeClass
* 功能 :构建类别信息网
* 说明 :定义类别信息结构体,通过串行构建类别信息网,保存类的相关信息
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CObject;
struct CRuntimeClass
{
// 类
LPCSTR m_lpszClassName; // 类别名
int m_nObjectSize; // 类别大小
UINT m_wSchema; // 模式
CObject* (PASCAL* m_pfnCreateObject)(); // 函数指针,指向类别中用于创建对象的函数
CRuntimeClass* m_pBaseClass; // 指向基类的类别信息结构体指针
// 信息网
static CRuntimeClass* pFirstClass; // 类别信息串行的头
CRuntimeClass* m_pNextClass; // 类别信息串行指针
};
/**************************************************************************************
* 结构体名 :AFX_CLASSINIT
* 功能 :全局类的初始化
* 说明 :通过其构造函数创建类别信息网的头部
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
struct AFX_CLASSINIT
{
//! 注意在C++中结构体也是有构造函数的
AFX_CLASSINIT(CRuntimeClass* pNewClass);
};
//! 通过宏将类注册到类别信息网中
//- 获取类别信息网中类的名字
#define RUNTIME_CLASS(class_name) \
(&class_name::class##class_name)
//- 在class_name 类别中添加类别信息结构体变量
//- 和一个获取该变量的函数GetRuntimeClass()
#define DECLARE_DYNAMIC(class_name) \
public: \
static CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const;
//- 头插法在类别信息串行头部插入class_name类别,
//- 将类别信息录入类别信息网中,
//- 定义GetRuntiemClass()
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
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; } \
//- 将class_name类的模式设为0xFFFF
//- 函数指针(指向类别中用于创建对象的函数)初始化为NULL
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)
//++ 构建MFC基本类别框架
/**************************************************************************************
* 类名称 :CObject
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CObject
{
public:
CObject() { }
~CObject() { }
// 特性
public:
static CRuntimeClass classCObject;
// 操作
public:
virtual CRuntimeClass* GetRuntimeClass() const;
};
/**************************************************************************************
* 类名称 :CCmdTarget
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CCmdTarget : public CObject
{
DECLARE_DYNAMIC(CCmdTarget)
public:
CCmdTarget() { }
~CCmdTarget() { }
};
/**************************************************************************************
* 类名称 :CWinThread
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CWinThread : public CCmdTarget
{
DECLARE_DYNAMIC(CWinThread)
public:
CWinThread() { }
~CWinThread() { }
// 操作
public:
virtual BOOL InitInstance() { return TRUE; }
virtual int Run() { return 1; }
};
/**************************************************************************************
* 类名称 :CWinApp
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CWnd;
class CWinApp : public CWinThread
{
DECLARE_DYNAMIC(CWinApp)
// 特性
public:
CWinApp* m_pCurrentWinApp;
CWnd* m_pMainWnd;
public:
CWinApp() { m_pCurrentWinApp = this; }
~CWinApp() { }
// 操作
public:
virtual BOOL InitApplication() { return TRUE; }
virtual BOOL InitInstance() { return TRUE; }
virtual int Run() { return CWinThread::Run(); }
};
/**************************************************************************************
* 类名称 :CDocument
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CDocument : public CCmdTarget
{
DECLARE_DYNAMIC(CDocument)
public:
CDocument() { }
~CDocument() { }
};
/**************************************************************************************
* 类名称 :CWnd
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CWnd : public CCmdTarget
{
DECLARE_DYNAMIC(CWnd)
public:
CWnd() { }
~CWnd() { }
// 操作
public:
virtual BOOL Create();
BOOL CreateEx();
virtual BOOL PreCreateWindow();
};
/**************************************************************************************
* 类名称 :CFrameWnd
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CFrameWnd : public CWnd
{
DECLARE_DYNAMIC(CFrameWnd)
public:
CFrameWnd() { }
~CFrameWnd() { }
// 操作
public:
BOOL Create();
virtual BOOL PreCreateWindow();
};
/**************************************************************************************
* 类名称 :CView
* 功能 :
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CView : public CWnd
{
DECLARE_DYNAMIC(CView)
public:
CView() { }
~CView() { }
};
// 全局操作
CWinApp* AfxGetApp();
// mfc.h end
mfc.cpp
/**************************************************************************************
* 文件名 :mfc.cpp
* 摘要 :定义MFC框架类的操作
* 作者 :张群伟
* 日期 :[4/2/2017]
* 历史记录 :
* 修改者: 日期: 版本: 修改内容:
*
**************************************************************************************/
#include "my.h"
extern CMyWinApp theApp;
// 类别信息串行的头需要特别定义
/*
* 录入头信息
*/
static char szCObject[] = "CObject";
CRuntimeClass CObject::classCObject = { szCObject, sizeof(CObject), 0xffff, NULL, NULL };
/*
* 定义全局静态变量_init_CObject,通过其构造函数创建类别信息串行的头部
*/
static AFX_CLASSINIT _init_CObject(&CObject::classCObject);
CRuntimeClass* CRuntimeClass::pFirstClass = NULL;
AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass)
{
pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;
CRuntimeClass::pFirstClass = pNewClass;
}
// CObject
CRuntimeClass* CObject::GetRuntimeClass() const
{
return &CObject::classCObject;
}
// CWnd
BOOL CWnd::Create()
{
return TRUE;
}
BOOL CWnd::CreateEx()
{
PreCreateWindow();
return TRUE;
}
BOOL CWnd::PreCreateWindow()
{
return TRUE;
}
// CFrameWnd
BOOL CFrameWnd::Create()
{
CreateEx();
return TRUE;
}
BOOL CFrameWnd::PreCreateWindow()
{
return TRUE;
}
// 注册类别信息
IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget)
IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
IMPLEMENT_DYNAMIC(CWnd, CCmdTarget)
IMPLEMENT_DYNAMIC(CFrameWnd, CWnd)
IMPLEMENT_DYNAMIC(CDocument, CCmdTarget)
IMPLEMENT_DYNAMIC(CView, CWnd)
// 全局操作
CWinApp* AfxGetApp()
{
return theApp.m_pCurrentWinApp;
}
my.h
/**************************************************************************************
* 文件名 :my.h
* 摘要 :通过类向导生成的MFC类框架,此处仿真将所有类都放到一个文件下便于理解,
* 类向导生成的则每一个类都有一个.h和.cpp文件
* 作者 :张群伟
* 日期 :[4/2/2017]
* 历史记录 :
* 修改者: 日期: 版本: 修改内容:
*
**************************************************************************************/
#include <iostream>
#include "mfc.h"
/**************************************************************************************
* 类名称 :CMyWinApp
* 功能 :程序类
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
class CMyWinApp : public CWinApp
{
public:
CMyWinApp() { }
~CMyWinApp() { }
public:
virtual BOOL InitInstance();
};
/**************************************************************************************
* 类名称 :CMyFrameWnd
* 功能 :框架类
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/6/2017]
**************************************************************************************/
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd();
~CMyFrameWnd() { }
};
/**************************************************************************************
* 类名称 :CMyDoc
* 功能 :资料类
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/6/2017]
**************************************************************************************/
class CMyDoc : public CDocument
{
public:
CMyDoc() { }
~CMyDoc() { }
};
/**************************************************************************************
* 类名称 :CMyView
* 功能 :显示类
* 当前版本 :1.0
* 作者 :张群伟
* 日期 :[4/6/2017]
**************************************************************************************/
class CMyView : public CView
{
public:
CMyView() { }
~CMyView() { }
};
// 全局操作
void PrintAllClasses();
// my.h end
my.cpp
/**************************************************************************************
* 文件名 :my.cpp
* 摘要 :
* 作者 :张群伟
* 日期 :[4/2/2017]
* 历史记录 :
* 修改者: 日期: 版本: 修改内容:
*
**************************************************************************************/
#include "my.h"
using namespace std;
// CMyWinApp
唯一的一个 CMyWinApp 对象
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance()
{
m_pMainWnd = new CMyFrameWnd;
return TRUE;
}
// CMyFrameWnd
CMyFrameWnd::CMyFrameWnd()
{
Create();
}
/**************************************************************************************
* 函数名 :PrintAllClass
* 功能 :打印类别信息网
* 参数 :void
* 返回值 : void
* 说明 :
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
void PrintAllClass(void)
{
CRuntimeClass* pClass;
for (pClass = CRuntimeClass::pFirstClass; pClass != NULL;
pClass = pClass->m_pNextClass)
{
cout << "\t类名: " << pClass->m_lpszClassName << endl;
cout << "\t大小: " << pClass->m_nObjectSize << endl;
cout << "\t模式: " << pClass->m_wSchema << endl;
if (pClass->m_pBaseClass != NULL)
{
cout << "\t基类名: " << pClass->m_pBaseClass->m_lpszClassName << endl;
}
cout << endl;
}
}
/**************************************************************************************
* 函数名 :main函数
* 功能 :MFC中被隐藏的main函数
* 参数 :void
* 返回值 : void
* 说明 :
* 作者 :张群伟
* 日期 :[4/2/2017]
**************************************************************************************/
int main(void)
{
cout << "main start !\n" << endl;
CWinApp* pApp = AfxGetApp();
// 完成每一个程序只做一次的动作
pApp->InitApplication();
// 完成每一个个体都得做一次的动作
pApp->InitInstance();
// 运行
pApp->Run();
// 打印类别信息网
PrintAllClass();
cout << "main end !" << endl;
getchar();
}
实验结果:
附上VS项目程序:
点击打开链接