深入浅出MFC笔记2

今天看了RTTI 的实现.理解了实现.

头文件里的DECLARE_DYNAMIC(C***)

实现文件里的IMPLEMENT_DYNAMIC(C***,CBase***)

这两个宏和

STRUCT AFX_CLASSINIT的构造函数用的实现好巧妙.

利用他们构造了一个链表.

  1. //mfc.h
  2. #ifndef  _MFC_H
  3. #define  _MFC_H
  4. #define BOOL int 
  5. #define TRUE    1
  6. #define FALSE   0
  7. #define LPCTSTR LPSTR
  8. typedef char *  LPSTR;
  9. #define UINT int 
  10. #define PASCAL _stdcall 
  11. #include <iostream>
  12. using namespace std;
  13. class CObject;
  14. struct CRuntimeClass
  15. {
  16.     //Attributes
  17.     LPCTSTR m_lpszClassName;
  18.     int     m_nObjectSize;
  19.     UINT    m_wSchema;//schema number of the loaded class
  20.     CObject* (PASCAL* m_pfnCreateObject)();//NULL=>abstract class
  21.     
  22.     CRuntimeClass *pBaseClass;
  23.     //CRuntimeClass objects linked together in simple list
  24.     static CRuntimeClass* pFirstClass;// start of class list 
  25.     CRuntimeClass * m_pNextClass;//linkedlist of registered calsses
  26. };
  27. struct AFX_CLASSINIT
  28. {
  29.     //constructor
  30.     AFX_CLASSINIT(CRuntimeClass * pNewClass);
  31. };
  32. #define RUNTIME_CLASS(class_name) /
  33.         (&class_name::class##class_name)
  34. #define DECLARE_DYNAMIC(class_name) /
  35. public: /
  36.     static CRuntimeClass class##class_name; /
  37.     virtual CRuntimeClass*  GetRuntimeClass() const;
  38. #define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew) /
  39.         static char _lpsz##class_name[]=#class_name; /
  40.         CRuntimeClass class_name::class##class_name={ /
  41.                 _lpsz##class_name, sizeof(class_name), wSchema, pfnNew, /
  42.                         RUNTIME_CLASS(base_class_name), NULL }; /
  43.         static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); /
  44.         CRuntimeClass* class_name::GetRuntimeClass() const /
  45.                 { return &class_name::class##class_name; } /
  46. #define     IMPLEMENT_DYNAMIC(class_name,base_class_name) /
  47.          _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)
  48. class CObject
  49. {
  50. public:
  51.     CObject()
  52.     {
  53.     }
  54.     ~CObject()
  55.     {
  56.     }
  57.     virtual CRuntimeClass * GetRuntimeClass() const ;
  58. public:
  59.     static CRuntimeClass classCObject;
  60. };
  61. class CCmdTarget : public CObject
  62. {
  63.     DECLARE_DYNAMIC(CCmdTarget)
  64. public:
  65.     CCmdTarget()
  66.     {
  67.     }
  68.     ~CCmdTarget()
  69.     {
  70.     }
  71. };
  72. /
  73. class CWinThread: public CCmdTarget
  74. {
  75.      DECLARE_DYNAMIC(CWinThread)
  76. public:
  77.     CWinThread()
  78.     {
  79.     }
  80.     ~CWinThread()
  81.     {
  82.     }
  83.     virtual BOOL InitInstance()
  84.     {
  85.         return TRUE;
  86.     }
  87.     virtual int Run()
  88.     {
  89.         return 1;
  90.     }
  91. };
  92. ///
  93. class CWnd;
  94. class CWinApp: public CWinThread
  95. {
  96.    DECLARE_DYNAMIC(CWinApp)
  97. public:
  98.     CWinApp* m_pCurrentWinApp;
  99.     CWnd*   m_pMainWnd;
  100. public:
  101.     CWinApp()
  102.     {
  103.         m_pCurrentWinApp=this;
  104.     }
  105.     ~CWinApp()
  106.     {
  107.     }
  108.     virtual BOOL InitApplication()
  109.     {
  110.         return TRUE;
  111.     }
  112.     virtual BOOL InitInstance()
  113.     {
  114.         return TRUE;
  115.     }
  116.     virtual int Run()
  117.     {
  118.         return CWinThread::Run();
  119.     }
  120. };
  121. /
  122. class CDocument : public CCmdTarget
  123. {
  124.     DECLARE_DYNAMIC(CDocument)
  125. public:
  126.     CDocument()
  127.     {
  128.     }
  129.     ~CDocument()
  130.     {
  131.     }
  132. };
  133. ///
  134. class CWnd : public CCmdTarget
  135. {
  136.      DECLARE_DYNAMIC(CWnd)
  137. public:
  138.     CWnd()
  139.     {
  140.     }
  141.     ~CWnd()
  142.     {
  143.     }
  144.     virtual BOOL Create();
  145.     BOOL    CreateEx();
  146.     virtual BOOL PreCreateWindow();
  147. };
  148. class CFrameWnd : public CWnd
  149. {
  150.     DECLARE_DYNAMIC(CFrameWnd)
  151. public:
  152.     CFrameWnd()
  153.     {
  154.     }
  155.     ~CFrameWnd()
  156.     {
  157.     }
  158.     virtual BOOL Create();
  159.     virtual BOOL PreCreateWindow();
  160. };
  161. /
  162. class CView : public CWnd
  163. {
  164.     DECLARE_DYNAMIC(CView)
  165. public:
  166.     CView()
  167.     {
  168.     }
  169.     ~CView()
  170.     {
  171.     }
  172. };
  173. //global function
  174. CWinApp * AfxGetApp();
  175. #endif
  176. //my.h
  177. #ifndef _MY_H
  178. #define _MY_H
  179. #include <iostream>
  180. #include "MFC.H"
  181. using namespace std;
  182. class CMyWinApp : public CWinApp
  183. {
  184. public:
  185.     CMyWinApp()
  186.     {
  187.     }
  188.     ~CMyWinApp()
  189.     {
  190.     }
  191.     virtual BOOL InitInstance();
  192. };
  193. class CMyFrameWnd : public CFrameWnd
  194. {
  195. public:
  196.     CMyFrameWnd();
  197.     ~CMyFrameWnd()
  198.     {
  199.     }
  200. };
  201. /
  202. class CMyDoc: public CDocument
  203. {
  204. public:
  205.     CMyDoc()
  206.     {
  207.     }
  208.     ~CMyDoc()
  209.     {
  210.     }
  211. };
  212. class CMyView: public CView
  213. {
  214. public:
  215.     CMyView()
  216.     {
  217.     }
  218.     ~CMyView()
  219.     {
  220.     }
  221. };
  222. void PrintAllClasses();
  223. #endif
  224. //mfc.cpp
  225. #include "my.h"
  226. extern CMyWinApp theApp;
  227. static char szCObject[]="CObject";
  228. struct CRuntimeClass CObject::classCObject=
  229. { szCObject,sizeof(CObject),0xffff,NULL,NULL,NULL};
  230.     static AFX_CLASSINIT _init_CObject(& CObject::classCObject);
  231.     CRuntimeClass * CRuntimeClass::pFirstClass=NULL;
  232.     AFX_CLASSINIT::AFX_CLASSINIT( CRuntimeClass * pNewClass)
  233.     {
  234.         pNewClass->m_pNextClass=CRuntimeClass::pFirstClass;
  235.         CRuntimeClass::pFirstClass=pNewClass;
  236.     }
  237.     CRuntimeClass *  CObject::GetRuntimeClass() const
  238.     {
  239.         return & CObject::classCObject;
  240.     }
  241.     BOOL CWnd::Create()
  242.     {
  243.         return TRUE;
  244.     }
  245.     BOOL CWnd::CreateEx()
  246.     {
  247.       PreCreateWindow();
  248.       return TRUE;
  249.     }
  250.    
  251.     BOOL CWnd::PreCreateWindow()
  252.     {
  253.         return TRUE;
  254.     }
  255.     BOOL CFrameWnd::Create()
  256.     {
  257.         CreateEx();
  258.         return TRUE;
  259.     }
  260.     BOOL CFrameWnd::PreCreateWindow()
  261.     {
  262.         return TRUE;
  263.     }
  264.     IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
  265.     IMPLEMENT_DYNAMIC(CWinThread,CCmdTarget)
  266.     IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
  267.     
  268.     IMPLEMENT_DYNAMIC(CWnd,CCmdTarget)
  269.     IMPLEMENT_DYNAMIC(CFrameWnd,CWnd)
  270.     IMPLEMENT_DYNAMIC(CDocument,CCmdTarget)
  271.     IMPLEMENT_DYNAMIC(CView,CWnd)
  272.     //global funciton
  273.     CWinApp * AfxGetApp()
  274.     {
  275.         return theApp.m_pCurrentWinApp;
  276.     }
  277. //my.cpp
  278. #include "my.h"
  279. CMyWinApp theApp;
  280. BOOL CMyWinApp::InitInstance()
  281. {
  282.     m_pMainWnd=new CMyFrameWnd;
  283.     return TRUE;
  284. }
  285. CMyFrameWnd::CMyFrameWnd()
  286. {
  287.    Create();
  288. }
  289. void PrintAllClasses()
  290. {
  291.    CRuntimeClass* pClass;
  292.    //just walk through the simple list of registered classes
  293.    for(pClass=CRuntimeClass::pFirstClass; pClass !=NULL; pClass=pClass->m_pNextClass)
  294.    {
  295.        cout<<pClass->m_lpszClassName<<endl;
  296.        cout<<pClass->m_nObjectSize<<endl;
  297.        cout<<pClass->m_wSchema<<endl;
  298.    }
  299. }
  300. ///
  301. /
  302. ///
  303. void main()
  304. {
  305.     CWinApp * pApp =AfxGetApp();
  306.     pApp->InitApplication();
  307.     pApp->InitInstance();
  308.     pApp->Run();
  309.     PrintAllClasses();
  310. }
  311.       

 

 

为了加深印象,边理解边打了一变.终于理解了宏的缺点,一出现问题,很难找到错误.

我把  _lpsz##class_name,sizeof(class_name),wSchema,pfnNew, /

打成了 lpsz##class_name,sizeof(class_name),wSchema,pfnNew, /

就漏了一个_符号.出现了许多莫名的错误.

 

宏真是一把双刃剑啊.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值