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

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>
            亚洲尤物视频在线| 日韩一区二区精品在线观看| 在线日韩中文字幕| 国产一区二区| 依依成人综合视频| 最新国产成人在线观看| 亚洲国产精品女人久久久| 亚洲精品美女久久久久| 一区二区三区欧美成人| 亚洲欧美日韩在线观看a三区| 亚洲欧美日韩一区二区三区在线| 欧美一区日本一区韩国一区| 欧美亚洲系列| 免费在线欧美视频| 99亚洲一区二区| 久久国产精品第一页| 欧美成人蜜桃| 国产欧美日韩中文字幕在线| 亚洲人成绝费网站色www| 亚洲你懂的在线视频| 免费成人性网站| 亚洲私人影院在线观看| 久久综合色婷婷| 国产精品久久午夜夜伦鲁鲁| 一区一区视频| 亚洲欧美电影院| 欧美激情精品久久久久久蜜臀| 99热在这里有精品免费| 久久久久久999| 国产精品亚洲美女av网站| 91久久精品国产91久久| 久久国产视频网站| 99精品欧美一区| 美女日韩欧美| 黄页网站一区| 久久精品国产久精国产思思| 99精品福利视频| 久久综合九色| 狠狠色狠狠色综合| 欧美亚洲免费电影| 亚洲精选久久| 免费欧美视频| 尤物精品在线| 久久久亚洲国产天美传媒修理工| 一区二区三区日韩在线观看| 欧美国产视频在线观看| 亚洲第一网站免费视频| 久久综合狠狠综合久久激情| 亚洲曰本av电影| 亚洲黄色av| 99www免费人成精品| 久久久久国内| 国产一区999| 亚洲日本黄色| 欧美在线视频二区| 日韩西西人体444www| 麻豆精品在线观看| 狠狠色丁香婷婷综合久久片| 久久不见久久见免费视频1| 在线一区二区三区四区| 欧美日韩高清在线一区| 亚洲人成网站777色婷婷| 久久色在线观看| 久久成人精品无人区| 国产视频在线观看一区 | 黄色成人免费观看| 久久国产精品网站| 午夜亚洲影视| 国产主播精品| 模特精品在线| 欧美精品首页| 欧美精品在线观看播放| 国产美女精品在线| 一区二区三区免费看| 亚洲三级观看| 欧美成人一品| 亚洲午夜国产一区99re久久| 国产精品99久久99久久久二8| 欧美日韩在线直播| 午夜影视日本亚洲欧洲精品| 欧美专区在线播放| 91久久久一线二线三线品牌| 日韩视频在线观看免费| 欧美午夜宅男影院| 亚洲视频精选| 亚洲国产精品第一区二区 | 亚洲裸体视频| 久久人人爽人人爽爽久久| 国产精品毛片| 媚黑女一区二区| 欧美精品成人一区二区在线观看| 中文日韩欧美| 亚洲作爱视频| 国产综合久久| 亚洲精品乱码久久久久久日本蜜臀| 欧美日韩国产一区二区三区| 欧美一级视频一区二区| 亚洲第一福利社区| 亚洲社区在线观看| 国产精品亚洲产品| 欧美3dxxxxhd| 夜夜嗨一区二区三区| 亚洲婷婷在线| 在线成人激情| 亚洲免费在线电影| 亚洲乱码国产乱码精品精天堂| 亚洲欧美日韩在线一区| 亚洲国产影院| 欧美一级免费视频| 亚洲高清免费| 午夜在线播放视频欧美| 亚洲精品国产拍免费91在线| 亚洲欧美国产毛片在线| 9l视频自拍蝌蚪9l视频成人| 久久精品123| 午夜电影亚洲| 欧美精品免费在线| 免费视频久久| 狠色狠色综合久久| 亚洲欧美清纯在线制服| 亚洲婷婷在线| 欧美伦理影院| 亚洲黄一区二区三区| 亚洲福利免费| 久久一区二区精品| 狂野欧美性猛交xxxx巴西| 国产亚洲精品v| 午夜精品区一区二区三| 亚洲一区二区在线免费观看视频| 欧美大片免费| 最近中文字幕日韩精品| 亚洲国产小视频| 毛片一区二区| 免费视频一区| 亚洲国产欧美日韩精品| 另类成人小视频在线| 欧美成人免费大片| 亚洲国产婷婷香蕉久久久久久| 久久久久久久综合日本| 久久另类ts人妖一区二区| 国产亚洲精品一区二区| 欧美一区二视频在线免费观看| 亚洲免费在线精品一区| 国产精品―色哟哟| 性色av一区二区怡红| 久久亚洲一区二区三区四区| 精品av久久707| 欧美大片一区二区三区| 亚洲久久一区| 欧美一级一区| 一区在线观看| 欧美日韩视频不卡| 午夜精品久久久久久久99热浪潮 | 欧美在线一区二区三区| 国产精品美女久久久久久免费| 亚洲天堂免费观看| 久久久青草婷婷精品综合日韩 | 亚洲国产综合在线看不卡| 老司机精品视频一区二区三区| 亚洲国产一区二区三区a毛片| 亚洲精品免费一二三区| 欧美va天堂| 亚洲性线免费观看视频成熟| 中国成人黄色视屏| 欧美三区美女| 午夜激情综合网| 巨胸喷奶水www久久久免费动漫| 亚洲高清免费视频| 国产精品va在线播放我和闺蜜| 亚洲自拍偷拍福利| 美女精品自拍一二三四| 一本久久知道综合久久| 国产欧美丝祙| 欧美不卡福利| 亚洲一区国产| 亚洲成人在线视频网站| 亚洲一区欧美激情| 国产一区二区三区免费在线观看| 麻豆精品一区二区综合av| 在线午夜精品自拍| 免费亚洲一区二区| 在线视频欧美日韩| 国内成人精品一区| 欧美午夜视频网站| 媚黑女一区二区| 性欧美videos另类喷潮| 亚洲美女精品久久| 久久一区二区三区超碰国产精品| 99精品欧美一区二区三区| 国产一区二区三区无遮挡| 欧美激情一区二区三区全黄| 亚洲欧美成人精品| 日韩写真视频在线观看| 欧美刺激午夜性久久久久久久| 翔田千里一区二区| 日韩一区二区免费高清| 在线日韩av| 国产一二精品视频| 国产精品毛片一区二区三区 | 欧美一区二区精美|