MFC永久保存机制--serialize数据读写

为了让自定义类能够有永久保存功能,需要重载》和《操作符,及其对serialize函数的重写,因此定义了宏DECLARE_SERIAL/IMPLEMENT_SERIAL

#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; } \

 

为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否是第一次出现、记录版本号码、记录文件名等工作,CRuntimeClass结构需要2个函数Load和Store:

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
#ifdef _AFXDLL
 CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
 CRuntimeClass* m_pBaseClass;
#endif

// 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;
};

 

CRuntimeClass* PASCAL CRuntimeClass::Load(CArchive& ar, UINT* pwSchemaNum)

{

  WORD nLen;

  char szClassName[64];

  CRuntimeClass* pClass;

  

  ar >> (WORD&)(*pwSchemaNum) >> nLen;

  if(nLen >= sizeof(szClassName) || ar.Read(szClassName, nLen) != nLen )

    return NULL;

  szClassName[nLen] = '\0';

  for(pClass = pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)

  {

    if(llstrcmp(szClassName,pClass->m_lpszClassName) == 0)

      return pClass;

  }

    return NULL;

}

 

void CRuntimeClass::Store(CArchive& ar) const

{

  WORD nLen = (WORD)lstrlenA(m_lpszClassName);

  ar << (WORD)m_wSchema << nLen;

  ar.Write(m_lpszClassName, nLen*sizeof(char));

}

你可能感兴趣的:(Serialize)