MFC原理第四讲.动态创建机制
MFC原理第四讲.动态创建机制
一丶要学习的知识点以及简介
动态创建是什么意思?
动态创建其实就是跟C++的new一样.都是创建对象.但是规避了C++语法的缺陷.
例如:
char * ClassName = "CMyApp"
CObject *obj = new ClassName;
C++ 中不允许这样编写代码
要学习的知识点
1.DECLARE_DYNCREATE 宏 学过上讲RTTI的应该明白.这个就是个文字替换. 也可以说这个宏是一个声明宏 当然也有实现宏
2.IMPLEMENT_DYNCREATE
还需要了解CRuntimeClass 结构. 支持动态创建的成员.
struct CRuntimeClass
{ LPCSTR m_lpszClassName; 类名
int m_nObjectSize; 类大小
UINT m_wSchema; 类编号
CObject* (PASCAL* m_pfnCreateObject)(); 存放支持动态创建的类 CRuntimeClass* m_pBaseClass; // Operations
CObject* CreateObject(); 动态创建函数
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; 判断函数 ...
CRuntimeClass* m_pNextClass; 链表存储执向下一个 };
二丶如何使用动态创建.
支持动态创建的是跟窗口有关的. 也就是CFrameWnd类. 如果我们继承了这个类.我们也可以让他支持动态创建.
1.添加声明宏
2.添加实现宏
3.动态创建使用.
添加声明宏 则添加到我们继承CFrameWnd类中即可. 实现宏则在外边
参数填写自己的类名
添加实现宏

使用动态创建. 在InitInstance里面使用即可.我们的new 窗口改成动态创建即可.

RUNTIME_CLASS宏可以拆解开.
m_pMainWnd = (CMainWnd *)((CRuntimeClass*)(&CMainWnd::classCMainWnd))->CreateObject();
应用程序实现截图:

三丶动态创建实现原理 之 宏 拆开
我们要看实现原理.当然要把宏拆看看看做了什么事情了.
1. DECLARE_DYNCREATE 宏拆开
#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \ RTTI动态识别
static CObject* PASCAL CreateObject();
我们可以看到这个宏 包含了我们的RTTI 类型识别. 并且添加了一个新的 成员函数
static Cobject * Createobject();
RTTI动态识别.上一讲已将讲过了. 就是添加了一个 CRuntimeClass 成员.以及获取成员的方法. 本次不讲解.
全部解开的宏
public:
static const CRuntimeClass classCMainWnd; 指针
virtual CRuntimeClass* GetRuntimeClass() const; 获取这个指针的函数 static CObject* PASCAL CreateObject(); 新增的函数
2.实现宏拆开 IMPLEMENT_DYNCREATE
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject, NULL) 其中还包含了一个宏 IMPLEMENT_RUNTIMECLASS
也进行拆开.
#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); }
第一个宏 IMPLEMENT_DYNCREATE 其实就是对 CreateObject进行实现. 也就是返回自己本身的 创建的类
第二个宏就是对 自己本身的结构体成员进行初始化.并且实现虚函数获取自己的这个成员. 跟RTTI一样.只不过初始化的时候.结构体初始化的值不一样.也就是我们上面说的CRuntimeClass结构中的新增的两个
成员进行了赋值.
解析的代码
//IMPLEMENT_DYNCREATE(CMainWnd,CFrameWnd) CObject* PASCAL CMainWnd::CreateObject()
{
return new CMainWnd;
} const CRuntimeClass CMainWnd::classCMainWnd =
{
"CMainWnd", sizeof(class CMainWnd), 0xFFFF, CMainWnd::CreateObject, 添加了自己的成员函数指针.其余地方一样 这个函数指针创建自己本身对象并且返回.
RUNTIME_CLASS(CFrameWnd), NULL, NULL
};
CRuntimeClass* CMainWnd::GetRuntimeClass() const
{
return RUNTIME_CLASS(CMainWnd);
}
所以远离就是CRuntime里面添加自己创建对象的函数指针. 然后自己的类中实现这个函数.创建自己的对象并且返回
这个就是动态创建了.
MFC原理第四讲.动态创建机制的更多相关文章
- MFC原理第六讲.消息传递
---恢复内容开始--- MFC原理第六讲.消息传递 一丶简介 通过上一讲我们的消息映射表.我们得知. 消息映射表 会保存父类的MessageMap 以及自己当前的消息结构体数组. 消息传递是一层一层 ...
- Springboot定时任务原理及如何动态创建定时任务
一.前言 上周工作遇到了一个需求,同步多个省份销号数据,解绑微信粉丝.分省定时将销号数据放到SFTP服务器上,我需要开发定时任务去解析文件.因为是多省份,服务器.文件名规则.数据规则都不一定,所以要做 ...
- [转载] java的动态代理机制详解
转载自http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代 ...
- Java 动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- java的动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- Java的动态代理机制详解(转)
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- (转)java的动态代理机制详解
原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一 ...
- InvocationHandler和Proxy(Class)的动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- 【Java深入研究】5、Proxy动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
随机推荐
- django中views中方法的request参数
知其然亦要知其所以然 views每个方法的参数都是request,那么问题来了,request为何物? 首先,几乎每个方法都是取数据(无论是从数据库,还是从第三方接口),然后进行一定的处理,之后传给前 ...
- python实现异步调用函数
import time from concurrent.futures import ThreadPoolExecutor def RunBenchmark(url): print('GET %s' ...
- 实现PHP服务端和c#客户端数据交换
服务端实现功能1,数据库的访问dbhelper.php包括执行语句返回多行,返回json数据,返回单条记录,返回第一行第一列的整数,返回第一行第一列的浮点数,返回第一行第一列的双精度数,返回第一行第一 ...
- U盘安装centos7 关键步骤
出现安装界面 按tab键或e键进行修改 一般默认第二行为: vmlinuz intrd=initrd.img inst.stage2=hd:LABEL=CentOS\x207\x20x86_64 rd ...
- 使用Eclipse的代码追踪功能
在使用Java编写复杂一些的程序时,你会不会常常对一层层的继承关系和一次次方法的调用感到迷惘呢?幸亏我们有了Eclipse这么好的IDE可以帮我们理清头绪--这就要使用Eclipse强大的代码追踪功能 ...
- 我的C#跨平台之旅(四):使用AOP(filter、attribute)进行系统增强
1.使用OData提速REST API开发 引入NuGet包:Microsoft.AspNet.WebApi.OData 在启动类中添加如下配置(示例为全局配置,也可基于Controller或Acti ...
- Mimikatz 法国神器
0x00 标准模块 Module : standardFull name : Standard moduleDescription : Basic commands (does not require ...
- html-有趣的标签-会移动的文字
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 通过URL触发Jenkins构建
用Jenkins做持续集成时,一般会使用webhooks触发构建,或者定时构建,这里记录用URL的方式触发Jenkins构建. Note: This assumes you're using Jenk ...
- 使用clipBoard.js进行页面内容复制
官方网址: https://clipboardjs.com/