MFC框架仿真---(1)类别信息网

本次仿真的主要内容有:

  • 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项目程序: 点击打开链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值