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

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精品| 亚洲精品欧美在线| 欧美中文在线视频| 久久夜色精品国产| 亚洲国产成人精品久久| 欧美啪啪一区| 亚洲一区二区在线视频| 另类国产ts人妖高潮视频| 在线欧美亚洲| 欧美另类亚洲| 亚洲视频在线观看免费| 国产精品久久久爽爽爽麻豆色哟哟| 亚洲综合日韩中文字幕v在线| 久久亚洲不卡| 日韩视频在线免费观看| 国产精品毛片在线| 六十路精品视频| 日韩亚洲精品电影| 久久久www免费人成黑人精品 | 欧美三级资源在线| 亚洲欧美国产不卡| 欧美高清一区二区| 午夜国产精品视频| 91久久中文字幕| 国产嫩草一区二区三区在线观看 | 久久久久成人精品免费播放动漫| 在线精品国产欧美| 国产精品sm| 老司机精品视频网站| 宅男噜噜噜66一区二区| 欧美高清你懂得| 欧美亚洲日本国产| av成人黄色| 一区二区三区在线视频观看| 欧美视频日韩视频| 麻豆久久精品| 欧美在线观看一区二区| 一本色道久久99精品综合| 欧美a级一区| 欧美一区日韩一区| 亚洲小说区图片区| 亚洲激情中文1区| 国产在线拍偷自揄拍精品| 欧美图区在线视频| 欧美国产综合| 久久亚洲精品一区| 欧美一区二区在线| 亚洲一区二区免费视频| 亚洲国产成人高清精品| 久久另类ts人妖一区二区| 午夜精品一区二区三区在线| 一个人看的www久久| 亚洲区国产区| 亚洲精品1区2区| 永久域名在线精品| 一区二区三区在线高清| 国产日韩欧美三区| 国产精品视频内| 国产精品高精视频免费| 欧美日韩精品一区二区在线播放 | 韩国精品一区二区三区| 国产精品尤物福利片在线观看| 欧美日韩一区二区三区视频| 欧美激情 亚洲a∨综合| 欧美成人精品激情在线观看| 久久人人97超碰国产公开结果| 久久黄色级2电影| 欧美一区三区三区高中清蜜桃| 亚洲欧美日韩天堂| 亚洲欧美日韩天堂一区二区| 亚洲欧美视频在线观看| 先锋资源久久| 欧美中文字幕在线播放| 午夜亚洲一区| 欧美中文字幕视频在线观看| 欧美专区亚洲专区| 久久精品视频在线| 久久久久久久精| 欧美不卡福利| 欧美日产一区二区三区在线观看 | 欧美一区成人| 久久免费视频一区| 麻豆视频一区二区| 欧美国产欧美综合 | 国产精品视频999| 国产精品美女久久久久av超清| 国产精品视频一二三| 国产免费观看久久黄| 国产一区再线| 亚洲激情社区| 亚洲综合导航| 久久精品91| 欧美电影专区| 一区二区三区欧美在线| 亚洲欧美日韩成人| 久久综合色播五月| 欧美日韩亚洲网| 国产色视频一区| 亚洲国产91精品在线观看| 日韩香蕉视频| 欧美一区二区三区视频免费| 玖玖国产精品视频| 亚洲片在线资源| 午夜精品一区二区三区四区| 久久精品在线免费观看| 欧美激情亚洲精品| 国产色婷婷国产综合在线理论片a| 在线免费日韩片| 午夜精品电影| 欧美激情精品久久久久久免费印度 | 久久久综合网站| 亚洲国产影院| 亚洲欧美激情四射在线日 | 日韩一级黄色片| 欧美一区二区视频97| 欧美成人精品在线| 国产目拍亚洲精品99久久精品| 亚洲欧洲日韩在线| 久久成人在线| 亚洲精品视频啊美女在线直播| 性欧美大战久久久久久久免费观看| 欧美jizzhd精品欧美巨大免费| 国产精品自拍视频| 日韩视频精品在线| 久久精品亚洲一区二区| 亚洲精品日韩在线| 久久久亚洲精品一区二区三区 | 亚洲日本欧美日韩高观看| 性欧美办公室18xxxxhd| 欧美日本国产| 亚洲国产裸拍裸体视频在线观看乱了 | 欧美高清成人| 久久xxxx| 国产精品一国产精品k频道56| 亚洲精品国产视频| 老司机精品视频一区二区三区| 中日韩视频在线观看| 欧美电影专区| 在线精品视频一区二区| 欧美在线黄色| 亚洲性视频h| 欧美日韩在线播放一区| 亚洲日韩第九十九页| 久久免费观看视频| 欧美一区二区三区视频免费| 国产精品久久久久久久久久ktv | 亚洲一区激情| 国产精品美女在线| 亚洲午夜一区二区三区| 亚洲人成网在线播放| 蜜臀av一级做a爰片久久| 极品少妇一区二区| 久久影视精品| 久久久www成人免费精品| 国产日韩成人精品| 欧美在线视频网站| 午夜精品久久久久久久99樱桃| 国产精品美女www爽爽爽| 亚洲女同在线| 亚洲综合第一页| 国产乱码精品一区二区三| 午夜欧美电影在线观看| 中文亚洲免费| 国产欧美精品xxxx另类| 午夜宅男欧美| 午夜精品久久久久久久男人的天堂| 国产精品久久久久久久久久免费看| 亚洲网站在线| 亚洲男女毛片无遮挡| 国产欧美精品日韩| 久久久久久久高潮| 久久久久.com| 亚洲人久久久| 日韩视频精品| 国产精品在线看| 久久男人av资源网站| 久久综合电影| 日韩视频在线免费观看| 一本色道久久综合亚洲精品高清 | 最新中文字幕一区二区三区| 欧美破处大片在线视频| 亚洲一区图片| 欧美亚洲一区三区| 亚洲福利免费| 一本色道久久88综合亚洲精品ⅰ| 国产精品一区二区a| 久久亚洲国产精品日日av夜夜| 久久婷婷亚洲| 日韩视频一区二区三区在线播放| 亚洲免费观看视频| 国产欧美三级| 亚洲国产精品成人精品| 国产精品久久久久77777| 久久男人资源视频| 欧美另类人妖| 久久精品中文| 欧美激情精品久久久久久免费印度| 亚洲欧美国产不卡| 久久蜜臀精品av| 亚洲尤物精选|