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

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文件中加上這兩個方法的定義。
當然這所有的代碼都是由系統(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 閱讀(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>
            亚洲黄一区二区| 欧美日本簧片| 亚洲动漫精品| 欧美14一18处毛片| 欧美第一黄色网| 亚洲精品1区| 日韩系列欧美系列| 亚洲主播在线播放| 欧美在线视频免费| 免费观看成人| 国产精品av久久久久久麻豆网| 国产精品美女一区二区在线观看| 国产欧美一区二区三区沐欲| 极品尤物久久久av免费看| 亚洲国产精品悠悠久久琪琪| 日韩视频永久免费观看| 亚洲免费视频网站| 久热精品视频在线| 亚洲精品一区二区三区樱花| 亚洲深夜福利在线| 欧美怡红院视频| 蜜桃av噜噜一区| 欧美另类视频| 国产精品视频999| 亚洲天堂网在线观看| 欧美一级大片在线免费观看| 欧美在线亚洲| 免费视频一区| 欧美三级视频在线播放| 国产精品国产精品国产专区不蜜| 国产精品免费一区二区三区观看| 国产亚洲精久久久久久| 韩国精品久久久999| 亚洲国产精品电影| 亚洲色图自拍| 久久精品99久久香蕉国产色戒| 蜜桃av噜噜一区| 久久深夜福利免费观看| 亚洲三级免费电影| 亚洲小说春色综合另类电影| 久久精品99国产精品日本| 欧美在线影院在线视频| 欧美成人国产一区二区 | 久久深夜福利| 欧美 日韩 国产一区二区在线视频| 国产视频精品免费播放| 国产欧美日韩三区| 一色屋精品视频在线观看网站| 亚洲国产日韩精品| 亚洲一区二区三区影院| 久久偷看各类wc女厕嘘嘘偷窃| 91久久精品一区| 性欧美xxxx大乳国产app| 蜜臀av国产精品久久久久| 国产精品久久久久毛片软件| 黄色精品一区二区| 亚洲欧美日韩精品久久奇米色影视| 免费成人小视频| 一区二区三区四区国产精品| 久久人人97超碰人人澡爱香蕉| 欧美日韩国产精品| 国模大胆一区二区三区| 亚洲视频一区二区免费在线观看| 久久人人97超碰人人澡爱香蕉 | 一区二区免费在线视频| 久久久久久成人| 欧美成人一区二区| 亚洲在线一区| 亚洲精品日韩久久| 亚洲免费影视| 欧美激情第三页| 国产在线成人| 欧美在线播放| 亚洲一区二区三区四区视频 | 久久综合网色—综合色88| 亚洲特级毛片| 欧美日韩精品国产| 一区二区三区黄色| 亚洲大片免费看| 久久久久久网| 精品动漫3d一区二区三区| 欧美亚洲自偷自偷| 亚洲主播在线播放| 国产欧美日韩一区| 欧美一区91| 久久爱www| 伊人伊人伊人久久| 欧美成人精品在线| 久久午夜激情| 玉米视频成人免费看| 久久婷婷麻豆| 狂野欧美一区| 亚洲裸体视频| 最近中文字幕日韩精品| 欧美成在线视频| 宅男噜噜噜66一区二区| 亚洲精品一区在线观看| 欧美日韩中国免费专区在线看| 一区二区三区欧美日韩| 一区二区日韩精品| 国产日本欧美在线观看| 欧美日韩国产999| 在线精品亚洲| 久久久久久久尹人综合网亚洲| 欧美高清影院| 国产一区二区三区不卡在线观看| 新狼窝色av性久久久久久| 午夜精品福利电影| 国内精品久久国产| 欧美成人久久| 欧美成人激情视频| 亚洲一区二区黄色| 欧美一区二区免费| 在线观看日韩www视频免费| 欧美国产日韩xxxxx| 欧美一区二区三区免费看| 国产伦精品免费视频| 欧美在线播放一区二区| 久久久精品国产99久久精品芒果| 亚洲精品一区二区在线| 亚洲网站在线看| 依依成人综合视频| 一区二区三区欧美视频| 狠狠色丁香久久婷婷综合丁香| 欧美高清不卡在线| 国产精品久久久久久影视| 欧美成年人在线观看| 欧美日韩久久精品| 免费观看成人www动漫视频| 欧美午夜大胆人体| 欧美大片在线观看一区| 国产精品女主播| 亚洲欧洲一区二区在线观看| 国产目拍亚洲精品99久久精品| 亚洲第一级黄色片| 国内视频一区| 亚洲视频久久| 国产一区再线| 一本大道久久a久久精品综合| 精品91在线| 午夜在线视频观看日韩17c| 亚洲精品在线观| 久久精品国产第一区二区三区最新章节| 日韩视频免费在线观看| 久久精品国产69国产精品亚洲| 在线综合亚洲| 欧美aaa级| 久久人人爽人人| 国产精品男女猛烈高潮激情| 91久久久久久| 亚洲国产一区二区在线| 久久精品二区| 久久精品国产91精品亚洲| 国产精品成人免费精品自在线观看| 亚洲国产精品一区二区三区| 亚洲电影免费观看高清| 久久精品人人做人人爽电影蜜月| 日韩视频在线永久播放| 久久亚洲精选| 欧美电影免费观看网站| 狠狠色2019综合网| 久久久人成影片一区二区三区观看 | 在线观看亚洲一区| 亚洲精品一区中文| 亚洲经典自拍| 蜜臀久久99精品久久久画质超高清| 久久久99国产精品免费| 国产日产欧产精品推荐色| 亚洲欧美精品suv| 久久国产精彩视频| 国产日本欧美一区二区三区| 亚洲一二三区精品| 午夜精品www| 国产日韩欧美三级| 久久久99国产精品免费| 久久婷婷一区| 亚洲精品国产精品国产自| 欧美成人精品不卡视频在线观看 | 免费日本视频一区| 在线观看亚洲精品| 欧美激情一区二区三区在线视频观看| 亚洲国产欧美一区二区三区久久| 亚洲免费观看高清完整版在线观看熊 | 久久国产精品久久久久久久久久| 国产精品外国| 另类欧美日韩国产在线| 亚洲国产日韩欧美在线图片| 中日韩美女免费视频网址在线观看| 欧美成人一区二区三区| 欧美国产一区二区| 亚洲视频在线一区观看| 国产亚洲视频在线| 欧美成人免费一级人片100| 一本到高清视频免费精品| 欧美一区视频| 亚洲日本成人| 国产精品欧美日韩一区| 狂野欧美激情性xxxx| 亚洲视频 欧洲视频| 免费人成网站在线观看欧美高清|