class CDynamicClassTestDlg : public CDialogEx
{
DECLARE_DYNAMIC(CDynamicClassTestDlg)
}
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static const CRuntimeClass class##class_name; \
static CRuntimeClass* PASCAL GetThisClass(); \
virtual CRuntimeClass* GetRuntimeClass() const; \
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static const CRuntimeClass classCDynamicClassTestDlg;
static CRuntimeClass* PASCAL GetThisClass();
virtual CRuntimeClass* GetRuntimeClass() const;
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
CRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL, class_init }; \
CRuntimeClass* PASCAL class_name::GetThisClass() \
{ return _RUNTIME_CLASS(class_name); } \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return _RUNTIME_CLASS(class_name); }
CRuntimeClass* PASCAL CDynamicClassTestDlg::_GetBaseClass()
{
return (CDialogEx::GetThisClass());
}
AFX_COMDAT const CRuntimeClass CDynamicClassTestDlg::classCDynamicClassTestDlg =
{
"CDynamicClassTestDlg" ,
sizeof(class CDynamicClassTestDlg),
0xFFF,
NULL,
&CDynamicClassTestDlg::_GetBaseClass,
NULL,
NULL
};
CRuntimeClass* PASCAL CDynamicClassTestDlg::GetThisClass()
{
return ((CRuntimeClass*)(&CDynamicClassTestDlg::classCDynamicClassTestDlg));
}
CRuntimeClass* CDynamicClassTestDlg::GetRuntimeClass() const
{
return ((CRuntimeClass*)(&CDynamicClassTestDlg::classCDynamicClassTestDlg));
}
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* (PASCAL* m_pfnGetBaseClass)();
// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
// dynamic name lookup and creation
static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);
static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);
// Implementation
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);
// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes
const AFX_CLASSINIT* m_pClassInit;
};
BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
{
// simple SI case
const CRuntimeClass* pClassThis = this;
for (;;)
{
if (pClassThis == pBaseClass)
return TRUE;
if (pClassThis->m_pfnGetBaseClass == NULL)
break;
pClassThis = (*pClassThis->m_pfnGetBaseClass)();
}
return FALSE; // walked to the top, no match
}
// not serializable, but dynamically constructable
#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* PASCAL CreateObject();
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject, NULL)
#define DECLARE_SERIAL(class_name) \
_DECLARE_DYNCREATE(class_name) \
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);
#define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
extern AFX_CLASSINIT _init_##class_name; \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \
class_name::CreateObject, &_init_##class_name) \
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \
return ar; }
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static const CRuntimeClass classCDynamicClassTestDlg;
static CRuntimeClass* PASCAL GetThisClass();
virtual CRuntimeClass* GetRuntimeClass() const;
protected:
static const AFX_MSGMAP* PASCAL GetThisMessageMap();
virtual const AFX_MSGMAP* GetMessageMap() const;
//DECLARE_DYNCREATE新添加
static CObject* PASCAL CreateObject();
//DECLARE_SERIAL新添加
friend CArchive& AFXAPI operator>>(CArchive& ar, CDynamicClassTestDlg* &pOb);
CRuntimeClass* PASCAL CDynamicClassTestDlg::_GetBaseClass()
{
return (CDialogEx::GetThisClass());
}
extern AFX_CLASSINIT _init_CDynamicClassTestDlg;
AFX_COMDAT const CRuntimeClass CDynamicClassTestDlg::classCDynamicClassTestDlg =
{
"CDynamicClassTestDlg" ,
sizeof(class CDynamicClassTestDlg),
0xFFF,
NULL,
&CDynamicClassTestDlg::_GetBaseClass,
CDynamicClassTestDlg::CreateObject,
&_init_CDynamicClassTestDlg
};
CRuntimeClass* PASCAL CDynamicClassTestDlg::GetThisClass()
{
return ((CRuntimeClass*)(&CDynamicClassTestDlg::classCDynamicClassTestDlg));
}
CRuntimeClass* CDynamicClassTestDlg::GetRuntimeClass() const
{
return ((CRuntimeClass*)(&CDynamicClassTestDlg::classCDynamicClassTestDlg));
}
AFX_CLASSINIT _init_CDynamicClassTestDlg(RUNTIME_CLASS(CDynamicClassTestDlg));
CArchive& AFXAPI operator>>(CArchive& ar, CDynamicClassTestDlg* &pOb)
{
pOb = (CDynamicClassTestDlg*) ar.ReadObject(RUNTIME_CLASS(CDynamicClassTestDlg));
return ar;
}
// generate static object constructor for class registration
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
struct AFX_CLASSINIT
{
AFX_CLASSINIT(CRuntimeClass* pNewClass)
{
AfxClassInit(pNewClass);
}
};
未完待续