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

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 閱讀(4816) 評論(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>
            国产亚洲精品美女| 国产精品日本欧美一区二区三区| 亚洲欧美日韩国产一区二区三区 | 久久国产福利| 欧美专区日韩视频| 亚洲精品系列| 91久久亚洲| 亚洲精品欧美在线| 亚洲伦伦在线| 亚洲午夜三级在线| 欧美在线在线| 亚洲成色精品| 免费亚洲电影| 一区二区三区精品在线| 亚洲天堂免费在线观看视频| 在线亚洲一区| 免费欧美高清视频| 国产精品日日摸夜夜添夜夜av| 亚洲国产婷婷香蕉久久久久久99| 国产欧美日韩三级| 亚洲狠狠丁香婷婷综合久久久| 亚洲精品午夜| 欧美国产日韩一二三区| 日韩一级大片在线| 亚洲欧美日韩人成在线播放| 蜜桃久久精品乱码一区二区| 香蕉乱码成人久久天堂爱免费| 久久亚洲免费| 久久精品国产第一区二区三区最新章节 | 国产美女精品视频免费观看| 久久一二三四| 亚洲美女黄色| 一区二区精品| 亚洲视频中文字幕| 亚洲素人在线| 性久久久久久久久久久久| 久久精品二区三区| 国产精品一二三视频| 国产一区二区三区直播精品电影| 国产精品视频自拍| 在线观看欧美日本| 国产在线一区二区三区四区| 国产主播一区| 宅男精品导航| 久久久蜜桃精品| 日韩视频一区二区三区在线播放免费观看 | 国产精品福利影院| 久久精品卡一| 欧美午夜精品久久久久久浪潮 | 国产日韩欧美综合在线| 狠狠入ady亚洲精品| 99在线热播精品免费| 久久字幕精品一区| 亚洲一区在线视频| 欧美精品乱码久久久久久按摩| 久久精品视频免费| 欧美精品日韩www.p站| 国产裸体写真av一区二区| 亚洲精品视频二区| 欧美**人妖| 欧美一区二区三区久久精品| 中文国产成人精品| 欧美黄色一级视频| 亚洲精品美女91| 另类亚洲自拍| 久久夜色精品国产噜噜av| 国产精品毛片一区二区三区 | 久久综合伊人77777麻豆| 欧美区一区二| 欧美日韩在线免费| 中文国产亚洲喷潮| 在线激情影院一区| 亚洲午夜精品| 亚洲欧美三级伦理| 欧美日本一区二区高清播放视频| 亚洲国产另类精品专区| 欧美ed2k| 国产精品欧美久久久久无广告| 艳女tv在线观看国产一区| 一本大道久久a久久精品综合 | 欧美精品大片| 亚洲影视综合| 欧美一区二区三区婷婷月色 | 日韩午夜在线视频| 欧美成人精品h版在线观看| 久久久www成人免费毛片麻豆 | 欧美国产日韩免费| 欧美大片国产精品| 香港久久久电影| 欧美大尺度在线观看| 欧美中文字幕精品| 欧美日韩美女在线| 欧美va天堂在线| 久久国产精品99久久久久久老狼 | 六十路精品视频| 中文一区在线| 久久久国产亚洲精品| 亚洲女与黑人做爰| 欧美成人精品影院| 久久躁日日躁aaaaxxxx| 国产精品h在线观看| 欧美成人免费全部| 欧美视频不卡中文| 最新精品在线| 国产一区二区三区在线观看视频 | 欧美日韩精品| 国产精品久久久久久久久久久久 | 欧美精品在线一区| 亚洲国产成人在线| 午夜视频在线观看一区| 欧美色精品天天在线观看视频| 久久久五月婷婷| 国产自产v一区二区三区c| 亚洲午夜激情| av成人免费在线| 欧美日韩午夜在线| 一本一本久久a久久精品综合麻豆| 亚洲国产视频一区二区| 午夜精品福利视频| 欧美精品久久久久久久| 亚洲国产精品久久人人爱蜜臀 | 最新成人av网站| 欧美一区二区成人| 伊人成人在线| 午夜久久福利| 在线观看视频日韩| 国产精品捆绑调教| 久久黄金**| 欧美一区激情视频在线观看| 国产一区二区三区最好精华液| 欧美日韩精品一区二区三区| 国产欧美视频一区二区三区| 亚洲国产高清一区| 久久aⅴ国产紧身牛仔裤| 亚洲国产精品va| 欧美一级视频免费在线观看| 噜噜噜在线观看免费视频日韩| 国产精品激情偷乱一区二区∴| 亚洲精品小视频| 欧美激情欧美激情在线五月| 久久国产精品久久久久久| 在线看欧美日韩| 亚洲国产日韩精品| 嫩草伊人久久精品少妇av杨幂| 一区二区三区日韩精品| 国产麻豆成人精品| 欧美不卡视频一区| 噜噜噜躁狠狠躁狠狠精品视频 | 亚洲国产精品一区二区三区| 欧美一区在线直播| 久久色中文字幕| 欧美成熟视频| 久久国产精品网站| 亚洲人成在线免费观看| 国产精品久久久久永久免费观看| 性久久久久久| 欧美伊久线香蕉线新在线| 国产精品乱码人人做人人爱| 亚洲欧美一区二区精品久久久| 亚洲高清av在线| 亚洲理论在线| 国产综合精品一区| 久久综合狠狠| 欧美国产视频在线观看| 国产欧美一区二区在线观看| 久久精品成人| 欧美日韩国产二区| 久久精品99无色码中文字幕| 久久久999精品免费| 中文精品视频一区二区在线观看| 亚洲精品国产日韩| 欧美日韩在线亚洲一区蜜芽| 久久狠狠久久综合桃花| 久久久午夜视频| 韩国三级在线一区| 久久亚洲高清| 国产日韩专区| 欧美一区亚洲二区| 香港成人在线视频| 国产精品美女久久久久av超清 | 国产欧美一区二区精品婷婷| av成人天堂| 欧美激情小视频| 欧美激情国产日韩| 亚洲黄色性网站| 久久超碰97中文字幕| 欧美11—12娇小xxxx| 国产精品福利在线观看| 亚洲国产精品久久久久婷婷老年| 91久久精品国产91性色tv| 欧美日韩一区在线观看| 先锋影音国产一区| 牛牛国产精品| 亚洲一区二区在| 一本久久综合亚洲鲁鲁| **性色生活片久久毛片| 亚洲综合精品一区二区| 亚洲欧美日韩在线播放| 国产精品日韩高清| 久久久久中文|