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的更多相关文章

  1. VC++/MFC 最常用宏和指令

    1.#include指令  包含指定的文件,最基本的最熟悉的指令,编程中不得不用,包含库文件用双尖括号,包含自定义头文件用双引号. 2.#define指令   预定义,通常用它来定义常量(包括无参量与 ...

  2. MFC 滑动条的重绘

    MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...

  3. MFC 按钮如何改变颜色

    我们发现想改变对话框的背景颜色是很简单的,但是对话框的背景颜色改变了后,我们发现按钮的颜色没有改变,如下图. 这样做出来的对话框看起来,不是很自然,我们也想把按钮的颜色改变一下.这就用到了按钮的重绘. ...

  4. 问题解决——CVSListBox的使用

    =================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载  请通过右 ...

  5. 深入浅出MFC[摘记]

    1.Windows程序的运行本质:基于消息,事件驱动(Message Based,Event Driven).2.程序调用GetMessage API循环获取消息,程序的生命靠它来推动. MSG ms ...

  6. MFC之TreeCtrl控件使用经验总结

    树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点.MFC中使用CTreeCtrl类来封装树形控件的各种操作.通过调用BOOL ...

  7. VC++ GDI 总结 一一 CBitmap类

    class CBitmap : public CGdiObject { DECLARE_DYNAMIC(CBitmap) public: static CBitmap* PASCAL FromHand ...

  8. VC++ CStatic控件背景透明且改变其文本时,文字重叠解决方法

    最近在项目中将CStatic控件设置为背景透明且在一个定时器函数改变其文本,结果CStatic的文字重叠了.解决该问题的方案是:从CStatic类派生自己的静态文本控件. 其实设置背景透明,也就是在C ...

  9. create()创建的控件不能映射消息函数的解决

    有时,使用create()在运行时创建的控件不能将消息映射到父窗口内,此时需要使用消息转发的机制,主要原理:注册一个全局的消息,针对接收消息的控件编写继承类,在该继承类中响应消息,并将已注册的全局消息 ...

随机推荐

  1. 条款39: 避免 "向下转换" 继承层次

    基类指针不能调用派生类的独有的成员,即使基类指针指向派生类对象,因为编译器是根据指针的静态类型来确定调用对象在内存中占据的空间的.此时可以使用static_cast来转换,但不要这么做,因为向下转换难 ...

  2. 【CV论文阅读】Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

    由RCNN到FAST RCNN一个很重要的进步是实现了多任务的训练,但是仍然使用Selective Search算法来获得ROI,而FASTER RCNN就是把获得ROI的步骤使用一个深度网络RPN来 ...

  3. 第5章 Cisco测试命令和TCP/IP连接故障处理

    第5章 Cisco测试命令和TCP/IP连接故障处理 一.故障处理命令 1.show命令: 1) 全局命令: show version :显示系统硬件和软件版本.DRAM.Flash show sta ...

  4. ViewPager + Handler 实现的图片自己主动轮播

    首先上图看效果 我也是在网上看各种大牛们做的效果,非常多都是自己定义重写了一些控件来实现这个效果的. 我把当中的一位大牛写的ViewPager的效果加上了Handler实现了自己主动轮播效果.在此做个 ...

  5. 【Cocos2dx游戏开发】CCNotificationCenter传递消息和数据

    在开发游戏的时候我们经常需要在层与层之间.场景与场景之间传递数据和消息,Cocos2dx框架应用观察者模式为我们封装了一个CCNotificationCenter类,也叫消息通知中心,它也是一个单例类 ...

  6. 常用样式制作思路 自定义按钮~自适应布局~常见bug seajs简记 初学者必知的HTML规范 不容忽略的——CSS规范

    常用样式制作思路   学习常用样式总结参考来自这里 带点文字链接列表利用:before实现 1 <!DOCTYPE html> 2 <html lang="en" ...

  7. The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)

    The 2014 ACM-ICPC Asia Mudanjiang Regional Contest 题目链接 没去现场.做的网络同步赛.感觉还能够,搞了6题 A:这是签到题,对于A堆除掉.假设没剩余 ...

  8. Tomcat PK Resin

    特征 Tomcat Resin 所属公司 Apache CAUCHO 用户数 多 少 可參考文档 多 少 与Eclipse集成复杂度 适中 较复杂. Eclipse下调试开发 简便 复杂.更新类后会自 ...

  9. HDOJ 题目2475 Box(link cut tree去点找祖先)

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  10. go语言笔记——go环境变量goroot是安装了路径和gopath是三方包路径

    Go 环境变量 Go 开发环境依赖于一些操作系统环境变量,你最好在安装 Go 之间就已经设置好他们.如果你使用的是 Windows 的话,你完全不用进行手动设置,Go 将被默认安装在目录 c:/go  ...