青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++博客 聯系 聚合 管理  

Blog Stats

文章分類(17)

收藏夾(2)

文章檔案(18)

相冊

Blogs

citywanderer

一、關于DECLARE_MESSAGE_MAP宏定義
使用MFC向導,在ApplicationType頁面選擇DialogBased,生成一個對話框項目,Dialog類命名為CCapturePacketDlg,在CCapturePacketDlg.cpp中自動產生下列代碼:

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為根節點也就是上面代碼中的行號,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); //為一個函數指針
3.2 AFX_PMSGW:typedef void (AFX_MSG_CALL CWnd::*AFX_PMSGW)(void);?? //為一個函數指針

將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);//函數指針

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;?\
注意函數為static,即它們是類的函數。函數中的static變量實際也在類對象未生成之前已經存在。(這種說法不知道是否正確?)
小結:
每次用MFC類向導生成一個類時,系統會在類的聲明部分添加兩個方法的聲明:GetThisMessageMap(),GetMessageMap()。在類的實現部分.cpp文件中加上這兩個方法的定義。
當然這所有的代碼都是由系統生成的,如果我們要定義自己的消息處理函數呢,例如,我們要添加一個按鈕(ID為:IDC_BUTTON1)的單擊處理函數我們可以添加宏ON_NOTIFY(NM_CLICK, IDC_BUTTON1, OnMyClick),OnMyClick為自定義函數,但是他必須與ON_NOTIFY中的函數原型一致。

二、關于DECLARE_DYNCREATE宏
使用MFC向導,在ApplicationType頁面選擇SingleDocument,生成一個單文檔項目,Document類命名為CDynamicDoc,在CDynamicDoc.h中自動產生DECLARE_DYNCREATE(CDynamicDoc),CDynamicDoc.cpp中產生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中的節點類型就是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()函數的功能簡單的如下表示:
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????}
小結:注意了,上面的成員變量、很多函數都是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),給出它們的宏定義及結果:
?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????}
總結,一旦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是一個結構體AFX_CLASSINIT的對象,此結構體有構造函數:
?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,也就調用了_init_CStroke的構造函數即將類CStroke添加到了全局變量m_classList類的List中了,同時在變量classCStroke中,也可以得到類CStroke的名稱、大小、一個CStroke的對象、類CStroke的基類以及AFX_CLASSINIT結構的一個對象。
posted on 2006-06-17 14:20 citywanderer 閱讀(4819) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美影院在线| 有码中文亚洲精品| 亚洲国产成人在线视频| 国产精品久久| 欧美激情一区二区| 国产在线高清精品| 亚洲视频免费在线| 99在线精品视频| 麻豆精品传媒视频| 久久久综合视频| 国产精品久久久久久久7电影| 免费影视亚洲| 一区二区亚洲欧洲国产日韩| 亚洲影院污污.| 亚洲欧美日韩国产综合| 欧美人成免费网站| 亚洲精选久久| 亚洲欧洲在线视频| 免费成人高清视频| 欧美黑人在线播放| 亚洲国产裸拍裸体视频在线观看乱了中文| 欧美亚洲视频一区二区| 香蕉久久一区二区不卡无毒影院 | 亚洲日本成人网| 亚洲福利在线视频| 久久久久久久网| 久久中文欧美| 精品动漫3d一区二区三区免费版 | 亚洲美女诱惑| 一区二区成人精品| 欧美日韩国语| 一区二区欧美在线观看| 亚洲欧美激情精品一区二区| 欧美视频在线观看免费| 中国女人久久久| 欧美一区二区三区喷汁尤物| 国产麻豆精品视频| 欧美一区在线直播| 玖玖玖国产精品| 亚洲黄色免费网站| 欧美日韩aaaaa| 亚洲小说欧美另类社区| 久久激五月天综合精品| 激情综合在线| 欧美国产日韩视频| 亚洲精品久久久久久下一站| 国产精品99久久久久久久女警 | 欧美精品在线免费观看| 亚洲每日在线| 久久av二区| 在线观看日韩| 欧美日韩福利| 亚洲欧美日韩国产一区二区三区| 久久久夜精品| 99re6热只有精品免费观看| 国产精品久久一区二区三区| 欧美在线视频导航| 亚洲精品国精品久久99热| 亚洲综合99| 韩国av一区二区| 欧美乱在线观看| 午夜一区在线| 亚洲黄色影片| 欧美一区二区三区四区在线观看地址| 韩国在线视频一区| 欧美日韩不卡合集视频| 性欧美暴力猛交另类hd| 亚洲国产成人av在线| 性欧美1819sex性高清| 一区二区亚洲欧洲国产日韩| 欧美日韩在线免费观看| 久久丁香综合五月国产三级网站| 亚洲黄色在线观看| 久久九九免费| 正在播放欧美视频| 在线观看亚洲视频| 国产精品久久二区| 欧美成人四级电影| 久久精品综合网| 亚洲一区二区三| 亚洲人成7777| 欧美国产一区二区三区激情无套| 亚洲综合三区| 99精品国产99久久久久久福利| 国产精品一区二区在线观看不卡| 欧美成人午夜77777| 午夜精彩国产免费不卡不顿大片| 亚洲人成人99网站| 噜噜噜在线观看免费视频日韩| 亚洲欧美区自拍先锋| 亚洲精品美女在线| 伊人天天综合| 韩国欧美一区| 国产综合网站| 国产麻豆成人精品| 国产精品久久亚洲7777| 欧美日韩成人综合在线一区二区 | 亚洲精品国产精品国自产观看| 国产精品三级久久久久久电影| 欧美日本久久| 欧美激情视频在线免费观看 欧美视频免费一| 欧美亚洲三区| 午夜激情一区| 香蕉乱码成人久久天堂爱免费 | 国产精品一区二区黑丝| 欧美午夜精品理论片a级大开眼界| 欧美成人午夜激情在线| 久久综合九色| 免费日韩av电影| 老司机免费视频久久| 久久尤物视频| 久久综合亚洲社区| 免费亚洲电影在线| 免费欧美网站| 欧美久久久久久久久| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美成人官网二区| 欧美xx视频| 亚洲欧洲免费视频| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美成人国产| 欧美韩日亚洲| 亚洲精品免费一二三区| 亚洲精品国偷自产在线99热| 亚洲人成网站在线观看播放| 亚洲区欧美区| 一区二区三区日韩精品视频| 亚洲午夜久久久久久尤物| 亚洲永久在线观看| 久久国产欧美精品| 免费成人av在线看| 欧美日韩视频专区在线播放| 国产精品激情电影| 狠狠色综合一区二区| 亚洲国产高清一区| 亚洲图片欧洲图片av| 欧美伊人久久久久久午夜久久久久 | 久久久一区二区| 欧美精品免费播放| 国产精品高潮呻吟久久av无限| 国产精品日韩久久久| 狠狠久久婷婷| 99热这里只有精品8| 亚洲欧美日本国产有色| 久久久综合精品| 亚洲人成在线观看网站高清| 99pao成人国产永久免费视频| 亚洲自拍偷拍视频| 久久这里只有精品视频首页| 欧美成人免费小视频| 国产精品成人一区二区网站软件 | 99国内精品久久| 欧美一区二区三区四区视频| 欧美3dxxxxhd| 亚洲一区精彩视频| 免费在线日韩av| 国产精品卡一卡二| 亚洲国产日韩欧美| 亚洲欧美第一页| 亚洲国产va精品久久久不卡综合| 亚洲视频香蕉人妖| 欧美成人嫩草网站| 韩曰欧美视频免费观看| 中国日韩欧美久久久久久久久| 久久三级视频| 亚洲一区二区三区视频播放| 久久综合免费视频影院| 国产伦精品一区二区三区视频孕妇 | 久久精品成人| 99热免费精品| 男人的天堂亚洲| 国产亚洲精品综合一区91| 一区二区三区高清在线观看| 久久一区中文字幕| 香蕉免费一区二区三区在线观看 | 亚洲欧美国产精品va在线观看| 免费观看一级特黄欧美大片| 亚洲四色影视在线观看| 欧美a一区二区| 国产一区深夜福利| 午夜精品99久久免费| 99精品欧美一区二区三区| 女仆av观看一区| 亚洲国产成人porn| 麻豆亚洲精品| 久久久噜噜噜久久狠狠50岁| 国产亚洲亚洲| 久久九九99| 久久本道综合色狠狠五月| 国产日韩欧美综合| 欧美一区二区福利在线| 在线亚洲精品| 国产精品乱码人人做人人爱| 一区二区三区四区五区在线| 亚洲三级免费观看| 欧美精品九九99久久| 日韩视频在线一区二区| 最新中文字幕一区二区三区| 欧美xart系列高清| 日韩午夜三级在线|