• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            C++博客 聯(lián)系 聚合 管理  

            Blog Stats

            文章分類(17)

            收藏夾(2)

            文章檔案(18)

            相冊

            Blogs

            citywanderer

            一、關(guān)于DECLARE_MESSAGE_MAP宏定義
            使用MFC向?qū)В贏pplicationType頁面選擇DialogBased,生成一個對話框項目,Dialog類命名為CCapturePacketDlg,在CCapturePacketDlg.cpp中自動產(chǎn)生下列代碼:

            1 BEGIN_MESSAGE_MAP(CCapturePacketDlg,?CDialog)
            2 ????ON_WM_PAINT()
            3 END_MESSAGE_MAP()
            1. 先來分析ON_WM_PAINT(),在頭文件“afxmsg.h”有它的宏定義,如下:
            1 #define ?ON_WM_PAINT()?\
            2 ???? {?WM_PAINT,? 0 ,? 0 ,? 0 ,?AfxSig_vv,?\
            3 ????????(AFX_PMSG)(AFX_PMSGW)?\
            4 ????????(static_cast < ? void ?(AFX_MSG_CALL?CWnd:: * )( void )? > ?(? & ThisClass?::?OnPaint))?}
            ,
            說明:層次序號x.y.z表示x為根節(jié)點也就是上面代碼中的行號,y、z為上一級的定義展開。
            2.1 #define WM_PAINT??????????????????????? 0x000F
            2.2 AfxSig_vv = AfxSig_v_v_v
            2.2.1 enum AfxSig::AfxSig_v_v_v = 19

            3.1 AFX_PMSG:typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void); //為一個函數(shù)指針
            3.2 AFX_PMSGW:typedef void (AFX_MSG_CALL CWnd::*AFX_PMSGW)(void);?? //為一個函數(shù)指針

            將ON_WM_PAINT()完全展開:
            1{
            2????????0x000F,?
            3????????0,
            4????????0,
            5????????0,
            6????????19,
            7????????//Converts?OnPaint?to?the?type?of?CCmdTarget?finally.?Derive?Class?'s?pointer?->?Base?Class's?pointer
            8????????(AFX_MSG_CALL?CCmdTarget::*)((AFX_MSG_CALL?CWnd::*)(static_cast<?void?(AFX_MSG_CALL?CWnd::*)(void)?>(&ThisClass?::?OnPaint))
            9????}

            ???2.???再來分析BEGIN_MESSAGE_MAP(CCapturePacketDlg, CDialog),在“afxwin.h”中有定義:

            ?1#define?BEGIN_MESSAGE_MAP(theClass,?baseClass)?\
            ?2????PTM_WARNING_DISABLE?\
            ?3????const?AFX_MSGMAP*?theClass::GetMessageMap()?const?\
            ?4????????{?return?GetThisMessageMap();?}?\
            ?5????const?AFX_MSGMAP*?PASCAL?theClass::GetThisMessageMap()?\
            ?6????{?\
            ?7????????typedef?theClass?ThisClass;???????????????????????????\
            ?8????????typedef?baseClass?TheBaseClass;???????????????????????\
            ?9????????static?const?AFX_MSGMAP_ENTRY?_messageEntries[]?=??\
            10????????{

            2.1 PTM_WARNING_DISABLE:
            #define PTM_WARNING_DISABLE \
            ?__pragma(warning( push ))??\?//#pragma warning( push [ ,n ] ),Where n represents a warning level (1 through 4).
            ????????????????????????????????????????????? //The pragma warning( push ) stores the current warning state for all warnings.
            ?__pragma(warning( disable : 4867 ))//Do not issue the specified warning message(s).
            //http://msdn2.microsoft.com/en-us/2c8f766e.aspx
            //?Allows selective modification of the behavior of compiler warning messages.
            3.1 struct AFX_MSGMAP
            ?{
            ??3.1.1 const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
            ??3.1.2 const AFX_MSGMAP_ENTRY* lpEntries;
            ?};
            3.1.2 struct AFX_MSGMAP_ENTRY
            ?{
            ??UINT nMessage;?? // windows message
            ??UINT nCode;????? // control code or WM_NOTIFY code
            ??UINT nID;??????? // control ID (or 0 for windows messages)
            ??UINT nLastID;??? // used for entries specifying a range of control id's
            ??UINT_PTR nSig;?????? // signature type (action) or pointer to message #
            ??3.1.2.1 AFX_PMSG pfn;??? // routine to call (or special value)
            ?};
            ?3.1.2.1 typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);

            5.1 #define PASCAL????? __stdcall
            將BEGIN_MESSAGE_MAP(CCapturePacketDlg, CDialog)完全展開:

            ?1__pragma(warning(?push?))?__pragma(warning(?disable?:?4867?))
            ?2????const?struct?AFX_MSGMAP*?CCapturePacketDlg::GetMessageMap()?const
            ?3????{?
            ?4????????return?GetThisMessageMap();?
            ?5????}

            ?6????const?struct?AFX_MSGMAP*?__stdcall?CCapturePacketDlg::GetThisMessageMap()
            ?7????{
            ?8????????typedef?CCapturePacketDlg?ThisClass;???????????????????????????
            ?9????????typedef?CDialog?TheBaseClass;????????
            10????????static?const?struct?AFX_MSGMAP_ENTRY?_messageEntries[]?=?
            11????????{

            ?? 3??? 最后分析END_MESSAGE_MAP(),在“afxwin.h”中有定義:

            1#define?END_MESSAGE_MAP()?\
            2????????{0,?0,?0,?0,?AfxSig_end,?(AFX_PMSG)0?}?\
            3????};?\
            4????????static?const?AFX_MSGMAP?messageMap?=?\
            5????????{?&TheBaseClass::GetThisMessageMap,?&_messageEntries[0]?};?\
            6????????return?&messageMap;?\
            7????}??????????????????????????????????\
            8????PTM_WARNING_RESTORE

            2.1 AfxSig_end:enum AfxSig.AfxSig_end = 0
            2.2 AFX_PMSG:typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);//函數(shù)指針

            4.1 struct AFX_MSGMAP
            ?{
            ??const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
            ??const AFX_MSGMAP_ENTRY* lpEntries;
            ?};

            8.1 #define PTM_WARNING_RESTORE \
            ?__pragma(warning( pop ))
            //pop restores the state of all warnings (including 4705, 4706, and 4707) to what it was at the beginning of the code.

            ·最后將

            1BEGIN_MESSAGE_MAP(CCapturePacketDlg,?CDialog)
            2????ON_WM_PAINT()
            3END_MESSAGE_MAP()
            完全展開為:
            ?1__pragma(warning(?push?))?__pragma(warning(?disable?:?4867?))
            ?2????const?struct?AFX_MSGMAP*?CCapturePacketDlg::GetMessageMap()?const
            ?3????{?
            ?4????????return?GetThisMessageMap();?
            ?5????}

            ?6????const?struct?AFX_MSGMAP*?__stdcall?CCapturePacketDlg::GetThisMessageMap()
            ?7????{
            ?8????????typedef?CCapturePacketDlg?ThisClass;???????????????????????????
            ?9????????typedef?CDialog?TheBaseClass;????????
            10????????static?const?struct?AFX_MSGMAP_ENTRY?_messageEntries[]?=?
            11????????{
            12????????????{
            13????????????????0x000F,?
            14????????????????0,
            15????????????????0,
            16????????????????0,
            17????????????????19,
            18????????????????//Converts?OnPaint?to?the?type?of?CCmdTarget?finally.?Derive?Class?'s?pointer?->?Base?Class's?pointer
            19????????????????(AFX_MSG_CALL?CCmdTarget::*)((AFX_MSG_CALL?CWnd::*)(static_cast<?void?(AFX_MSG_CALL?CWnd::*)(void)?>(&ThisClass?::?OnPaint))
            20????????????}
            ,
            21????????????//add?others
            22????????????{
            23????????????????0,
            24????????????????0,
            25????????????????0,
            26????????????????0,
            27????????????????0,
            28????????????????(AFX_PMSG)0
            29????????????}

            30????????}

            31????????static?const?struct?AFX_MSGMAP?messageMap?=?
            32????????{
            33????????????&TheBaseClass::GetThisMessageMap,
            34????????????&_messageEntries[0]
            35????????}
            ;
            36????????return?&messageMap;
            37????}

            38__pragma(warning(?pop?))
            39
            其中GetMessageMap()是在哪里聲明的呢?在CCapturePacketDlg的定義中有一個這樣的宏:DECLARE_MESSAGE_MAP()
            老辦法查看它的定義:
            1#define?DECLARE_MESSAGE_MAP()?\
            2protected:?\
            3????static?const?AFX_MSGMAP*?PASCAL?GetThisMessageMap();?\
            4????virtual?const?AFX_MSGMAP*?GetMessageMap()?const;?\
            注意函數(shù)為static,即它們是類的函數(shù)。函數(shù)中的static變量實際也在類對象未生成之前已經(jīng)存在。(這種說法不知道是否正確?)
            小結(jié):
            每次用MFC類向?qū)梢粋€類時,系統(tǒng)會在類的聲明部分添加兩個方法的聲明:GetThisMessageMap(),GetMessageMap()。在類的實現(xiàn)部分.cpp文件中加上這兩個方法的定義。
            當(dāng)然這所有的代碼都是由系統(tǒng)生成的,如果我們要定義自己的消息處理函數(shù)呢,例如,我們要添加一個按鈕(ID為:IDC_BUTTON1)的單擊處理函數(shù)我們可以添加宏ON_NOTIFY(NM_CLICK, IDC_BUTTON1, OnMyClick),OnMyClick為自定義函數(shù),但是他必須與ON_NOTIFY中的函數(shù)原型一致。

            二、關(guān)于DECLARE_DYNCREATE宏
            使用MFC向?qū)В贏pplicationType頁面選擇SingleDocument,生成一個單文檔項目,Document類命名為CDynamicDoc,在CDynamicDoc.h中自動產(chǎn)生DECLARE_DYNCREATE(CDynamicDoc),CDynamicDoc.cpp中產(chǎn)生IMPLEMENT_DYNCREATE(CDynamicDoc, CDocument)。
            1、展開CDynamicDoc.h中的DECLARE_DYNCREATE(CDynamicDoc):
            1//?not?serializable,?but?dynamically?constructable
            2????#define?DECLARE_DYNCREATE(class_name)?\
            3????????DECLARE_DYNAMIC(class_name)?\
            4????????static?CObject*?PASCAL?CreateObject();
            3.1如下定義:
            1#ifdef?_AFXDLL
            2????#define?DECLARE_DYNAMIC(class_name)?\
            3????protected:?\
            4????????static?CRuntimeClass*?PASCAL?_GetBaseClass();?\
            5????public:?\
            6????????static?const?CRuntimeClass?class##class_name;?\
            7????????static?CRuntimeClass*?PASCAL?GetThisClass();?\
            8????????virtual?CRuntimeClass*?GetRuntimeClass()?const;?\
            so the result(DECLARE_DYNCREATE(CDynamicDoc)) of combining the above two is following:
            1protected:?
            2????????static?CRuntimeClass*?PASCAL?_GetBaseClass();?
            3????public:?
            4????????static?const?CRuntimeClass?classCDynamicDoc;?
            5????????static?CRuntimeClass*?PASCAL?GetThisClass();?
            6????????virtual?CRuntimeClass*?GetRuntimeClass()?const;?
            7????????static?CObject*?PASCAL?CreateObject();

            2、展開CDynamicDoc.cpp中的IMPLEMENT_DYNCREATE(CDynamicDoc, CDocument):
            1#define?IMPLEMENT_DYNCREATE(class_name,?base_class_name)?\
            2????CObject*?PASCAL?class_name::CreateObject()?\
            3????????{?return?new?class_name;?}?\
            4????IMPLEMENT_RUNTIMECLASS(class_name,?base_class_name,?0xFFFF,?\
            5????????class_name::CreateObject,?NULL)
            4.1如下定義:
            ?1#define?IMPLEMENT_RUNTIMECLASS(class_name,?base_class_name,?wSchema,?pfnNew,?class_init)?\
            ?2????CRuntimeClass*?PASCAL?class_name::_GetBaseClass()?\
            ?3????????{?return?RUNTIME_CLASS(base_class_name);?}?\
            ?4????AFX_COMDAT?const?CRuntimeClass?class_name::class##class_name?=?{?\
            ?5????????#class_name,?sizeof(class?class_name),?wSchema,?pfnNew,?\
            ?6????????????&class_name::_GetBaseClass,?NULL,?class_init?}
            ;?\
            ?7????CRuntimeClass*?PASCAL?class_name::GetThisClass()?\
            ?8????????{?return?_RUNTIME_CLASS(class_name);?}?\
            ?9????CRuntimeClass*?class_name::GetRuntimeClass()?const?\
            10????????{?return?_RUNTIME_CLASS(class_name);?}?\
            4.1.2 CRuntimeClass如下定義:
            ?1struct?CRuntimeClass
            ?2????{
            ?3????//?Attributes
            ?4????????LPCSTR?m_lpszClassName;
            ?5????????int?m_nObjectSize;
            ?6????????UINT?m_wSchema;?//?schema?number?of?the?loaded?class
            ?7????????CObject*?(PASCAL*?m_pfnCreateObject)();?//?NULL?=>?abstract?class
            ?8????#ifdef?_AFXDLL
            ?9????????CRuntimeClass*?(PASCAL*?m_pfnGetBaseClass)();
            10????#else
            11????????CRuntimeClass*?m_pBaseClass;
            12????#endif
            13
            14????//?Operations
            15????????CObject*?CreateObject();
            16????????BOOL?IsDerivedFrom(const?CRuntimeClass*?pBaseClass)?const;
            17
            18????????//?dynamic?name?lookup?and?creation
            19????????static?CRuntimeClass*?PASCAL?FromName(LPCSTR?lpszClassName);
            20????????static?CRuntimeClass*?PASCAL?FromName(LPCWSTR?lpszClassName);
            21????????static?CObject*?PASCAL?CreateObject(LPCSTR?lpszClassName);
            22????????static?CObject*?PASCAL?CreateObject(LPCWSTR?lpszClassName);
            23
            24????//?Implementation
            25????????void?Store(CArchive&?ar)?const;
            26????????static?CRuntimeClass*?PASCAL?Load(CArchive&?ar,?UINT*?pwSchemaNum);
            27
            28????????//?CRuntimeClass?objects?linked?together?in?simple?list
            29????????CRuntimeClass*?m_pNextClass;???????//?linked?list?of?registered?classes
            30????????const?AFX_CLASSINIT*?m_pClassInit;
            31????}
            ;
            4.1.2.30 AFX_CLASSINIT如下定義:(這個變量非常重要,它完成了將新的類加在List頭部的功能,List中的節(jié)點類型就是CRuntimeClass)
            ?1/////////////////////////////////////////////////////////////////////////////
            ?2????//?Basic?object?model
            ?3
            ?4????//?generate?static?object?constructor?for?class?registration
            ?5????void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass);
            ?6????struct?AFX_CLASSINIT
            ?7????????{?AFX_CLASSINIT(CRuntimeClass*?pNewClass)?{?AfxClassInit(pNewClass);?}?};
            ?8????//C:\Program?Files\Microsoft?Visual?Studio?8\VC\atlmfc\src\mfc\objcore.cpp?Line157
            ?9????void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass)
            10????{
            11????????AFX_MODULE_STATE*?pModuleState?=?AfxGetModuleState();
            12????????AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
            13????????pModuleState->m_classList.AddHead(pNewClass);
            14????????AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
            15????}

            16????//可以將AfxClassInit()函數(shù)的功能簡單的如下表示:
            17????AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass*?pNewClass)
            18????{
            19????????pNewClass->m_pNextClass?=?CRuntimeClass::pFirstClass;
            20????????CRuntimeClass::pFirstClass?=?pNewClass;
            21????}

            4.1.3 RUNTIME_CLASS如下定義:
            1#define?RUNTIME_CLASS(class_name)?(class_name::GetThisClass())
            4.1.4 AFX_COMDAT如下定義:
            1#define?AFX_COMDAT?__declspec(selectany)
            說明:“#”——operator (#) converts macro parameters to string literals without expanding the parameter definition.
            “##”——operator (##), which is sometimes called the "merging" operator, is used in both object-like and function-like macros.
            4.1.8 _RUNTIME_CLASS如下定義:
            1#define?_RUNTIME_CLASS(class_name)?((CRuntimeClass*)(&class_name::class##class_name))
            so the result(IMPLEMENT_DYNCREATE(CDynamicDoc, CDocument)) of combining the aboves is following:
            ?1//CDynamicDoc,?CDocument->class_name,?base_class_name
            ?2??static??CObject*?PASCAL?CDynamicDoc::CreateObject()
            ?
            3????{?
            ?
            4????????return?new?CDynamicDoc;?
            ?
            5????}

            ?
            6
            ?
            7????static?CRuntimeClass*?PASCAL?CDynamicDoc::_GetBaseClass()
            ?
            8????{?
            ?
            9????????return?CDocument::GetThisClass()
            10????}

            11
            12????__declspec(selectany)?static?const?CRuntimeClass?CDynamicDoc::classCDynamicDoc?=?
            13????{
            14????????"CDynamicDoc"
            15????????,?sizeof(class?CDynamicDoc)
            16????????,?0xFFFF
            17????????,?CDynamicDoc::CreateObject
            18????????,?&CDynamicDoc::_GetBaseClass
            19????????,?NULL
            20????????,?NULL
            21????}
            ;
            22
            23????static?CRuntimeClass*?PASCAL?CDynamicDoc::GetThisClass()
            24????{
            25????????return?((CRuntimeClass*)(&CDynamicDoc::classCDynamicDoc));
            26????}

            27
            28????CRuntimeClass*?CDynamicDoc::GetRuntimeClass()?const
            29????{
            30????????return?((CRuntimeClass*)(&CDynamicDoc::classCDynamicDoc));
            31????}
            小結(jié):注意了,上面的成員變量、很多函數(shù)都是static
            如果你想看這些宏的簡化版,可以參考侯老的《深入淺出MFC》,如下:

            ?1//in?header?file
            ?2class?CView?:?public?CWnd
            ?3{
            ?4public:
            ?5????static?CRuntimeClass?classCView;
            ?6????virtual?CRuntimeClass*?GetRuntimeClass()?const;
            ?7????//……
            ?8}
            ;
            ?9//in?implementation?file
            10static?char_lpszCView?=?"CView";
            11CRuntimeClass?CView::classCView?=
            12{
            13????_lpszCView
            14????,?sizeof(CView)
            15????,?0xFFF
            16????,?NULL
            17????,?&CWnd::classCWnd
            18????,?NULL
            19}
            ;
            20static?AFX_CLASSINIT?_init_CView(&CView::classCView)
            21{
            22????(&CView::classCView)->m_pNextClass?=?CRuntimeClass::pFirstClass;
            23????CRuntimeClass::pFirstClass?=?&CView::classCView;
            24}

            25CRuntimeClass*?CView::GetRuntimeClass()?const
            26{
            27????return?&CView::classCView;
            28}
            其中他將CRuntimeClass簡化定義為:
            struct CRuntimeClass
            {
            // Attributes
            ??????? LPCSTR m_lpszClassName;
            ??????? int m_nObjectSize;
            ??????? UINT m_wSchema; // schema number of the loaded class
            ??????? CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
            ??????? CRuntimeClass* m_pBaseClass;

            ??????? // CRuntimeClass objects linked together in simple list
            ??????? static CRuntimeClass* pFirstClass; // start of class list
            ??????? CRuntimeClass* m_pNextClass;?????? // linked list of registered classes
            };

            三、宏DECLARE_SERIAL(CStroke)、IMPLEMENT_SERIAL(CStroke, CObject, 1),給出它們的宏定義及結(jié)果:
            ?1//declaration?file
            ?2#define?DECLARE_SERIAL(class_name)?\
            ?3????_DECLARE_DYNCREATE(class_name)?\
            ?4????AFX_API?friend?CArchive&?AFXAPI?operator>>(CArchive&?ar,?class_name*?&pOb);
            ?5
            ?6????#define?_DECLARE_DYNCREATE(class_name)?\
            ?7????_DECLARE_DYNAMIC(class_name)?\
            ?8????static?CObject*?PASCAL?CreateObject();
            ?9
            10????#define?_DECLARE_DYNAMIC(class_name)?\
            11????protected:?\
            12????????static?CRuntimeClass*?PASCAL?_GetBaseClass();?\
            13????public:?\
            14????????static?CRuntimeClass?class##class_name;?\
            15????????static?CRuntimeClass*?PASCAL?GetThisClass();?\
            16????????virtual?CRuntimeClass*?GetRuntimeClass()?const;?\
            17//implement?file
            18#define?IMPLEMENT_SERIAL(class_name,?base_class_name,?wSchema)?\
            19????CObject*?PASCAL?class_name::CreateObject()?\
            20????????{?return?new?class_name;?}?\
            21????extern?AFX_CLASSINIT?_init_##class_name;?\
            22????_IMPLEMENT_RUNTIMECLASS(class_name,?base_class_name,?wSchema,?\
            23????????class_name::CreateObject,?&_init_##class_name)?\
            24????AFX_CLASSINIT?_init_##class_name(RUNTIME_CLASS(class_name));?\
            25????CArchive&?AFXAPI?operator>>(CArchive&?ar,?class_name*?&pOb)?\
            26????????{?pOb?=?(class_name*)?ar.ReadObject(RUNTIME_CLASS(class_name));?\
            27????????????return?ar;?}
            ?\
            28????
            29????//?generate?static?object?constructor?for?class?registration
            30????void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass);
            31????struct?AFX_CLASSINIT
            32????????{?AFX_CLASSINIT(CRuntimeClass*?pNewClass)?{?AfxClassInit(pNewClass);?}?};
            33
            34????void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass)
            35????{
            36????????AFX_MODULE_STATE*?pModuleState?=?AfxGetModuleState();
            37????????AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
            38????????pModuleState->m_classList.AddHead(pNewClass);
            39????????AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
            40????}

            41
            42????
            43????#define?_IMPLEMENT_RUNTIMECLASS(class_name,?base_class_name,?wSchema,?pfnNew,?class_init)?\
            44????CRuntimeClass*?PASCAL?class_name::_GetBaseClass()?\
            45????????{?return?RUNTIME_CLASS(base_class_name);?}?\
            46????AFX_COMDAT?CRuntimeClass?class_name::class##class_name?=?{?\
            47????????#class_name,?sizeof(class?class_name),?wSchema,?pfnNew,?\
            48????????????&class_name::_GetBaseClass,?NULL,?class_init?}
            ;?\
            49????CRuntimeClass*?PASCAL?class_name::GetThisClass()?\
            50????????{?return?_RUNTIME_CLASS(class_name);?}?\
            51????CRuntimeClass*?class_name::GetRuntimeClass()?const?\
            52????????{?return?_RUNTIME_CLASS(class_name);?}?\
            53????
            54????#define?_RUNTIME_CLASS(class_name)?((CRuntimeClass*)(&class_name::class##class_name))
            55
            56????#define?RUNTIME_CLASS(class_name)?(class_name::GetThisClass())

            ?1//header?file
            ?2????protected:?
            ?3????????static?CRuntimeClass*?PASCAL?_GetBaseClass();?
            ?4????public:?
            ?5????????static?CRuntimeClass?classCStroke;?
            ?6????????static?CRuntimeClass*?PASCAL?GetThisClass();?
            ?7????????virtual?CRuntimeClass*?GetRuntimeClass()?const;?
            ?8????????static?CObject*?PASCAL?CreateObject();
            ?9????????AFX_API?friend?CArchive&?AFXAPI?operator>>(CArchive&?ar,?CStroke*?&pOb);
            10//implement?file
            11????//static
            12????static?CObject*?PASCAL?CStroke::CreateObject()
            13????{
            14????????return?new?CStroke;
            15????}

            16????//static
            17????static?CRuntimeClass*?PASCAL?CStroke::GetThisClass();
            18????{?
            19????????return?((CRuntimeClass*)(&CStroke::classCStroke))
            20????}

            21????//static
            22????static?CRuntimeClass*?PASCAL?CStroke::_GetBaseClass()?
            23????{?
            24????????return?(CObject::GetThisClass());
            25????}

            26????//static
            27????static?AFX_COMDAT?CRuntimeClass?CStroke::classCStroke?=?
            28????{
            29????????"CStroke"
            30????????,?sizeof(class?CStroke)
            31????????,?1
            32????????,?CStroke::CreateObject
            33????????,?&class_name::_GetBaseClass
            34????????,?NULL
            35????????,?&_init_CStroke?
            36????}
            ;?
            37????CRuntimeClass*?CStroke::GetRuntimeClass()?const
            38????{?
            39????????return?((CRuntimeClass*)(&CStroke::classCStroke));?
            40????}

            41????extern?struct?AFX_CLASSINIT?_init_CStroke;
            42????struct?AFX_CLASSINIT?_init_CStroke
            43????{
            44????????void?AFXAPI?AfxClassInit(CRuntimeClass*?CStroke)
            45????????{
            46????????????AFX_MODULE_STATE*?pModuleState?=?AfxGetModuleState();
            47????????????AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
            48????????????pModuleState->m_classList.AddHead(CStroke);
            49????????????AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
            50????????}

            51????}
            ;
            52????CArchive&?AFXAPI?operator>>(CArchive&?ar,?class_name*?&pOb)?
            53????{?
            54????????pOb?=?(CStroke*)?ar.ReadObject(RUNTIME_CLASS(CStroke));
            55????????return?ar;?
            56????}
            總結(jié),一旦RUNTIME_CLASS(CStroke)由#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())也就是CStroke::GetThisClass() 即
            CStroke::classCStroke =
            ?{
            ??"CStroke"
            ??, sizeof(class CStroke)
            ??, 1
            ??, CStroke::CreateObject
            ??, &class_name::_GetBaseClass
            ??, NULL
            ??, &_init_CStroke
            ?}
            其中,由extern AFX_CLASSINIT _initCStroke可知_init_CStroke是一個結(jié)構(gòu)體AFX_CLASSINIT的對象,此結(jié)構(gòu)體有構(gòu)造函數(shù):
            ?1void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass);
            ?2????struct?AFX_CLASSINIT
            ?3????????{?AFX_CLASSINIT(CRuntimeClass*?pNewClass)?{?AfxClassInit(pNewClass);?}?};
            ?4
            ?5????void?AFXAPI?AfxClassInit(CRuntimeClass*?pNewClass)
            ?6????{
            ?7????????AFX_MODULE_STATE*?pModuleState?=?AfxGetModuleState();
            ?8????????AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
            ?9????????pModuleState->m_classList.AddHead(pNewClass);
            10????????AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
            11????}
            所以一旦返回classCStroke,也就調(diào)用了_init_CStroke的構(gòu)造函數(shù)即將類CStroke添加到了全局變量m_classList類的List中了,同時在變量classCStroke中,也可以得到類CStroke的名稱、大小、一個CStroke的對象、類CStroke的基類以及AFX_CLASSINIT結(jié)構(gòu)的一個對象。
            posted on 2006-06-17 14:20 citywanderer 閱讀(4775) 評論(0)  編輯 收藏 引用 所屬分類: C++
            中文字幕无码免费久久| 欧美久久精品一级c片片| 成人久久免费网站| 亚洲午夜久久久影院| 99久久精品毛片免费播放| 97久久天天综合色天天综合色hd| 久久99精品久久久久久久久久| 国产精品视频久久| 欧美色综合久久久久久| 国产精品久久新婚兰兰| 久久精品人人做人人爽97| 亚洲国产二区三区久久| 亚洲成av人片不卡无码久久| 欧美一区二区三区久久综合| 99re这里只有精品热久久| 久久国产精品偷99| 一本久道久久综合狠狠爱| 狠色狠色狠狠色综合久久| 欧美与黑人午夜性猛交久久久| 伊人久久大香线蕉综合影院首页| 国产精品久久影院| 欧美久久久久久精选9999| 婷婷久久久亚洲欧洲日产国码AV| 94久久国产乱子伦精品免费| 国产A级毛片久久久精品毛片| 欧美综合天天夜夜久久| 伊人伊成久久人综合网777| 国产精品久久久久…| 国产欧美久久久精品影院| 国产精品久久国产精麻豆99网站| 欧美亚洲国产精品久久| 精品国产青草久久久久福利 | 久久久久亚洲AV综合波多野结衣| 久久久久亚洲AV无码专区首JN| 伊人久久免费视频| 99久久99久久精品国产片果冻| 久久精品国产色蜜蜜麻豆| 国内精品久久久久影院日本| 亚洲国产精品一区二区久久hs | 2021久久国自产拍精品| 久久午夜无码鲁丝片秋霞|