DECLARE_DYNAMIC
DECLARE_DYNAMIC(class_name)
DECLARE_DYNCREATE 包含了DECLARE_DYNAMIC的功能,并且可以在运行过程中动态创建对象。如果需要动态创建类对象,需要使用这个宏定义。
IMPLEMENT_DYNAMIC是实现“运行时类型识别”宏,与之相对应的是DECLARE_DYNAMIC(声明“运行时类型识别”宏)。也就是说你在.CPP文件中如果看见有IMPLEMENT_DYNAMIC,则在.H文件中必定有DECLARE_DYNAMIC的声明。
DECLARE_DYNAMIC/DEClARE_DYNAMIC是为了确定运行时对象属于哪一个类而定义的宏。
DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE是为了“动态创建"类的实例而定义的宏。new可以用来创建对象,但不是动态的。比如说,你要在程序中实现根据拥护输入的类名来创建类的实例,下面的做法是通不过的:
char szClassName[60];
cin >> szClassName;
CObject* pOb=new szClassName; //通不过
这里就要用到DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE定义的功能了。
定义:
//////////////////////////////////////////////////////////////////////////////
// Helper macros for declaring CRuntimeClass compatible classes
#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) /
protected: /
static CRuntimeClass* PASCAL _GetBaseClass(); /
public: /
static const CRuntimeClass class##class_name; /
static CRuntimeClass* PASCAL GetThisClass(); /
virtual CRuntimeClass* GetRuntimeClass() const; /
#define _DECLARE_DYNAMIC(class_name) /
protected: /
static CRuntimeClass* PASCAL _GetBaseClass(); /
public: /
static CRuntimeClass class##class_name; /
static CRuntimeClass* PASCAL GetThisClass(); /
virtual CRuntimeClass* GetRuntimeClass() const; /
#else
#define DECLARE_DYNAMIC(class_name) /
public: /
static const CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /
#define _DECLARE_DYNAMIC(class_name) /
public: /
static CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /
#endif
引用:
DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC
#define DECLARE_DYNAMIC(class_name)/
public:/
static CRuntimeClass class##class_name;/
//声明一个类型为CRuntimeClass的静态public成员变量,变量名是由字符串"class"
//与所指定的类的类名组成。举例而言,如果你写DECLARE_DYNAMIC(CMyView),则等于声明了一个
// static CRuntimeClass classCMyView静态变量
virtual CRuntimeClass* GetRuntimeClass() const;/
//声明一个虚函数,函数名为GetRuntimeClass,返回值为CRuntimeClass类型的指针
//无参数,并且是个const函数
#define IMPLEMENT_DYNAMIC(class_name,bass_class_name)/
_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)
#define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)/
static char _lpsz##class_name[]= #class_name;/
//定义一个C类型字符串静态变量,变量名由"_lpsz"和指定类的类名组成,变量值为该指定类型的名字
//比如是CMyView,那么定义的就是static char _lpszCMyView="CMyView";
CRuntimeClass class_name::class##class_name = {/
_lpsz##class_name,sizeof(class_name),wSchema,pfnNew,/
RUNTIME_CLASS(base_class_name),NULL};/
//给之前在DECLARE_DYNAMIC里定义的CRuntimeClass类型的静态成员变量赋值
//当然,除最后一个m_pNextClass没有赋值(赋值为NULL,它由下面的结构处理)
static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);/
//初始化一个名为"_init_##class_name"的AFX_CLASSINIT静态结构,主要作用是给指定的class_name的
//class##class_name静态变量的最后一个成员m_pNextClass赋值,具体见下面解释AFX_CLASSINIT中
CRuntimeClass* class_name::GetRuntimeClass() const/
{ return &class_name::class##class_name;}/
//之前在DECLARE_DYNAMIC里定义的GetRuntimeClass的实现,很简单,就一个return语句。
#define RUNTIME_CLASS(class_name)/
(&class_name::class##class_name)
//这部分之所以单独define出一个宏,主要是为了方便从某个指定的class直接得到它的CRuntimeclass静态成员
//以下是解释AFX_CLASSINIT结构,注意,这不是一个宏
//为了看得更加清楚,我按照struct定义的惯常格式来写这个struct的定义
struct AFX_CLASSINIT {
AFX_CLASSINIT(CRuntimeClass *pNewClass);
};
AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass *pNewClass)
{
pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;
//让m_pNextClass指向pFirstClass所指的CRuntimeClass变量
CRuntimeClass::pFirstClass = pNewClass;
//让pFirstClass指向pNewClass所指的变量,也就是本class的CRuntimeClass静态变量
}
DECLARE_DYNAMIC的更多相关文章
- VC++/MFC 最常用宏和指令
1.#include指令 包含指定的文件,最基本的最熟悉的指令,编程中不得不用,包含库文件用双尖括号,包含自定义头文件用双引号. 2.#define指令 预定义,通常用它来定义常量(包括无参量与 ...
- MFC 滑动条的重绘
MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...
- MFC 按钮如何改变颜色
我们发现想改变对话框的背景颜色是很简单的,但是对话框的背景颜色改变了后,我们发现按钮的颜色没有改变,如下图. 这样做出来的对话框看起来,不是很自然,我们也想把按钮的颜色改变一下.这就用到了按钮的重绘. ...
- 问题解决——CVSListBox的使用
=================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载 请通过右 ...
- 深入浅出MFC[摘记]
1.Windows程序的运行本质:基于消息,事件驱动(Message Based,Event Driven).2.程序调用GetMessage API循环获取消息,程序的生命靠它来推动. MSG ms ...
- MFC之TreeCtrl控件使用经验总结
树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点.MFC中使用CTreeCtrl类来封装树形控件的各种操作.通过调用BOOL ...
- VC++ GDI 总结 一一 CBitmap类
class CBitmap : public CGdiObject { DECLARE_DYNAMIC(CBitmap) public: static CBitmap* PASCAL FromHand ...
- VC++ CStatic控件背景透明且改变其文本时,文字重叠解决方法
最近在项目中将CStatic控件设置为背景透明且在一个定时器函数改变其文本,结果CStatic的文字重叠了.解决该问题的方案是:从CStatic类派生自己的静态文本控件. 其实设置背景透明,也就是在C ...
- create()创建的控件不能映射消息函数的解决
有时,使用create()在运行时创建的控件不能将消息映射到父窗口内,此时需要使用消息转发的机制,主要原理:注册一个全局的消息,针对接收消息的控件编写继承类,在该继承类中响应消息,并将已注册的全局消息 ...
随机推荐
- [Vue @Component] Write Vue Functional Components Inline
Vue's functional components are small and flexible enough to be declared inside of .vue file next to ...
- ORA-01925:maximum of 80 enabled roles exceeded
ORA-01925:maximum of 80 enabled roles exceeded max_enabled_roles 9i的參数,10g及以后都不用了. 指定用户session的最大ena ...
- Js跨一级域名同步cookie
1. 纯Js同步两个域名下的cookie document.cookie = "name=" + "value;" + "expires=" ...
- 汉澳Sinox2014X64server高级桌面服务器版操作系统公布
汉澳Sinox2014X64server高级桌面服务器版操作系统公布 当你在现代城市夜空中看到一道闪电.屏幕中央闪过几个图形,转眼间变成美轮美奂的紫色空中天国,说明你来到了汉澳sinox2014世 ...
- 【树剖求LCA】树剖知识点
不太优美但是有注释的版本: #include<cstdio> #include<iostream> using namespace std; struct edge{ int ...
- 2017iOS开发最新的打包测试步骤(亲测)
最近也是忙着修改项目,今天把最近遇到的问题和知识给大家分享一下. 有时候我们需要将我们的项目发给测试组进行bug测试,这时候我们就需要把自己的项目打包,生成一个二维码或者链接的形式,给测试组,接下来就 ...
- DVB-subtitle解析流程浅
DTV包含SUBTITLE和TTX. PMT中分别有不同的描述符对应,如下图的TTX descripter=0x56.语言ISO-639="fin" subtitle descri ...
- 使用centos 5.x 32位系统安装astgo 2014 v7.0教程(含全套安装文件)
版本特色: 全自动安装 安装过程中不用频繁输入yes或回车 自带完整号码归属地数据库 自带触屏版WAP ·首先确定你需要使用astgo 2014 7.0还是7.3: astgo 2014 v 7.0 ...
- 2-1 创建第一个Vue实例
https://cn.vuejs.org/ 生产版本是经过压缩后的版本,它里面把一些没用的警告的代码删除掉了所以它会更精悍一些. 直接引入CDN的网址我们就可以使用Vuejs了.使用生产版本或者CDN ...
- IBatis异常: Cannot find class: VARCHAR
今天再项目里添加新功能时,突然爆出 org.springframework.beans.factory.BeanCreationException: Error creating bean with ...