深入浅出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. ////////////////////////////////
  62. class CCmdTarget : public CObject
  63. {
  64.     DECLARE_DYNAMIC(CCmdTarget)
  65. public:
  66.     CCmdTarget()
  67.     {
  68.     }
  69.     ~CCmdTarget()
  70.     {
  71.     }
  72. };
  73. /////////////////////////////////////
  74. class CWinThread: public CCmdTarget
  75. {
  76.      DECLARE_DYNAMIC(CWinThread)
  77. public:
  78.     CWinThread()
  79.     {
  80.     }
  81.     ~CWinThread()
  82.     {
  83.     }
  84.     virtual BOOL InitInstance()
  85.     {
  86.         return TRUE;
  87.     }
  88.     virtual int Run()
  89.     {
  90.         return 1;
  91.     }
  92. };
  93. ///////////////////////////////////////
  94. class CWnd;
  95. class CWinApp: public CWinThread
  96. {
  97.    DECLARE_DYNAMIC(CWinApp)
  98. public:
  99.     CWinApp* m_pCurrentWinApp;
  100.     CWnd*   m_pMainWnd;
  101. public:
  102.     CWinApp()
  103.     {
  104.         m_pCurrentWinApp=this;
  105.     }
  106.     ~CWinApp()
  107.     {
  108.     }
  109.     virtual BOOL InitApplication()
  110.     {
  111.         return TRUE;
  112.     }
  113.     virtual BOOL InitInstance()
  114.     {
  115.         return TRUE;
  116.     }
  117.     virtual int Run()
  118.     {
  119.         return CWinThread::Run();
  120.     }
  121. };
  122. /////////////////////////////////////////////
  123. class CDocument : public CCmdTarget
  124. {
  125.     DECLARE_DYNAMIC(CDocument)
  126. public:
  127.     CDocument()
  128.     {
  129.     }
  130.     ~CDocument()
  131.     {
  132.     }
  133. };
  134. ///////////////////////////////////
  135. class CWnd : public CCmdTarget
  136. {
  137.      DECLARE_DYNAMIC(CWnd)
  138. public:
  139.     CWnd()
  140.     {
  141.     }
  142.     ~CWnd()
  143.     {
  144.     }
  145.     virtual BOOL Create();
  146.     BOOL    CreateEx();
  147.     virtual BOOL PreCreateWindow();
  148. };
  149. ////////////////////////////////////////
  150. class CFrameWnd : public CWnd
  151. {
  152.     DECLARE_DYNAMIC(CFrameWnd)
  153. public:
  154.     CFrameWnd()
  155.     {
  156.     }
  157.     ~CFrameWnd()
  158.     {
  159.     }
  160.     virtual BOOL Create();
  161.     virtual BOOL PreCreateWindow();
  162. };
  163. /////////////////////////////
  164. class CView : public CWnd
  165. {
  166.     DECLARE_DYNAMIC(CView)
  167. public:
  168.     CView()
  169.     {
  170.     }
  171.     ~CView()
  172.     {
  173.     }
  174. };
  175. //global function
  176. CWinApp * AfxGetApp();
  177. #endif
  178. //my.h
  179. #ifndef _MY_H
  180. #define _MY_H
  181. #include <iostream>
  182. #include "MFC.H"
  183. using namespace std;
  184. class CMyWinApp : public CWinApp
  185. {
  186. public:
  187.     CMyWinApp()
  188.     {
  189.     }
  190.     ~CMyWinApp()
  191.     {
  192.     }
  193.     virtual BOOL InitInstance();
  194. };
  195. class CMyFrameWnd : public CFrameWnd
  196. {
  197. public:
  198.     CMyFrameWnd();
  199.     ~CMyFrameWnd()
  200.     {
  201.     }
  202. };
  203. /////////////////////
  204. class CMyDoc: public CDocument
  205. {
  206. public:
  207.     CMyDoc()
  208.     {
  209.     }
  210.     ~CMyDoc()
  211.     {
  212.     }
  213. };
  214. ////////////////////////////////
  215. class CMyView: public CView
  216. {
  217. public:
  218.     CMyView()
  219.     {
  220.     }
  221.     ~CMyView()
  222.     {
  223.     }
  224. };
  225. void PrintAllClasses();
  226. #endif
  227. //mfc.cpp
  228. #include "my.h"
  229. extern CMyWinApp theApp;
  230. static char szCObject[]="CObject";
  231. struct CRuntimeClass CObject::classCObject=
  232. { szCObject,sizeof(CObject),0xffff,NULL,NULL,NULL};
  233.     static AFX_CLASSINIT _init_CObject(& CObject::classCObject);
  234.     CRuntimeClass * CRuntimeClass::pFirstClass=NULL;
  235.     AFX_CLASSINIT::AFX_CLASSINIT( CRuntimeClass * pNewClass)
  236.     {
  237.         pNewClass->m_pNextClass=CRuntimeClass::pFirstClass;
  238.         CRuntimeClass::pFirstClass=pNewClass;
  239.     }
  240.     CRuntimeClass *  CObject::GetRuntimeClass() const
  241.     {
  242.         return & CObject::classCObject;
  243.     }
  244.     BOOL CWnd::Create()
  245.     {
  246.         return TRUE;
  247.     }
  248.     BOOL CWnd::CreateEx()
  249.     {
  250.       PreCreateWindow();
  251.       return TRUE;
  252.     }
  253.    
  254.     BOOL CWnd::PreCreateWindow()
  255.     {
  256.         return TRUE;
  257.     }
  258.     BOOL CFrameWnd::Create()
  259.     {
  260.         CreateEx();
  261.         return TRUE;
  262.     }
  263.     BOOL CFrameWnd::PreCreateWindow()
  264.     {
  265.         return TRUE;
  266.     }
  267.     IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
  268.     IMPLEMENT_DYNAMIC(CWinThread,CCmdTarget)
  269.     IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
  270.     
  271.     IMPLEMENT_DYNAMIC(CWnd,CCmdTarget)
  272.     IMPLEMENT_DYNAMIC(CFrameWnd,CWnd)
  273.     IMPLEMENT_DYNAMIC(CDocument,CCmdTarget)
  274.     IMPLEMENT_DYNAMIC(CView,CWnd)
  275.     //global funciton
  276.     CWinApp * AfxGetApp()
  277.     {
  278.         return theApp.m_pCurrentWinApp;
  279.     }
  280. //my.cpp
  281. #include "my.h"
  282. CMyWinApp theApp;
  283. BOOL CMyWinApp::InitInstance()
  284. {
  285.     m_pMainWnd=new CMyFrameWnd;
  286.     return TRUE;
  287. }
  288. CMyFrameWnd::CMyFrameWnd()
  289. {
  290.    Create();
  291. }
  292. void PrintAllClasses()
  293. {
  294.    CRuntimeClass* pClass;
  295.    //just walk through the simple list of registered classes
  296.    for(pClass=CRuntimeClass::pFirstClass; pClass !=NULL; pClass=pClass->m_pNextClass)
  297.    {
  298.        cout<<pClass->m_lpszClassName<<endl;
  299.        cout<<pClass->m_nObjectSize<<endl;
  300.        cout<<pClass->m_wSchema<<endl;
  301.    }
  302. }
  303. ///////////////////////////////////////////
  304. /////////////////////////////////////////
  305. ///////////////////////////////////////
  306. void main()
  307. {
  308.     CWinApp * pApp =AfxGetApp();
  309.     pApp->InitApplication();
  310.     pApp->InitInstance();
  311.     pApp->Run();
  312.     PrintAllClasses();
  313. }
  314.       

 

 

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

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

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

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

 

宏真是一把双刃剑啊.

 

你可能感兴趣的:(c,struct,null,Class,mfc,pascal)