MFC的Serialize机制及其使用

简介: MFC的Serialize机制及其使用

一、CArchive类介绍


https://blog.csdn.net/weixin_45525272/article/details/106481559


二、序列化(Serialization)


MFC提供了非常方便的串行化函数Serialize()。利用这个机制可以很方便的对文档进行存取和读取。


1、 序列化提出和定义


序列化在面向对象的程序设计中出现的,它基于对象是可以连续的思想,在程序退出或者启动的时候,可以把对象顺序的存储在磁盘或者从磁盘读出,存储和读出对象的过程叫做序列化。


2、 序列化存储的应用和局限


序列化存储可以把对象存储到磁盘上,但它并不能代替数据库设计的信息存储,因为它只是顺序的存取,没有检索机制。


3、 序列化的类


序列化的类可以直接或者间接从CObject类派生,类的声明中必须包含DECLARE_SERIAL 宏调用,实现文件也必须有与之对应的宏:


IMPLEMENT_SERIAL。(注意: DECLARE_SERIAL/IMPLEMENT_SERIAL包含了DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏)。


4、 MFC中序列化的使用


如果应用程序没有进行直接磁盘操作的输入输出,而是依靠序列化的过程,那么就不必直接使用CFile对象。MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。

MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单File Open 和FileSave等过程中,应用程序框架会调用文档的Serialize函数,我们可以在该函数中处理特定类对象的序列化。


Serialization就是面向对象世界里面的永久生存机制,对象必须能够永久生存,也就是他们必须能够在程序结束时存储到文件当中,并且能够在程序重新激活时在恢复过来,存储和恢复对象的过程在MFC称之为Serialization,负责这项重要任务的是MFC Object类中的一个名为Serialize()的虚函数,文件的读写操作均通过它来方便的完成。


5、遵循步骤


一个类要支持Serializable,必须遵循以下步骤:


该类必须要继承自CObject


在该类的头文件中添加DECLARE_SERIAL宏


在该类的实现文件中添加 IMPLEMENT SERIAL宏


为该类添加一个缺省构造函数


在该类中重写Serialize( CArchive& ar )函数


之后,该类就可以被Serializable。


如何使用:


譬如我们新建一个MFC应用程序,为了方便处理数据,我们在程序中单独创建自己的类MyClass:


MyClass:public CObject
{
DECLARE_SERIAL(MyClass)     //很重要一定要加上
public:
   virtual void Serialize(CArchive& ar);
public:
   int m_iVal;
   float m_fVal;
};


在实现文件中:


IMPLEMENT_SERIAL(MyClass,CObject,1)
void MyClass::Serialize(CArchive& ar)
{
   if(ar.IsLoading())
   {
      //从文件中读取数据到内存中
      ar >> m_iVal;
      ar >> m_fVal;
   }
   else if(ar.IsStoring())
   {
      ar << m_iVal;
      ar << m_fVal;
   }
}


然后在MFC程序的C**Doc类中添加一个MyClass类型的对象myclass:


class C***Doc : public CDocument
{
public:
  C***Doc();
  DECLARE_DYNCREATE(C***Doc)
public:
  MyClass myclass;
public:
  virtual void Serialize(CArchive& ar);
*******
}


并且在C***Doc类的Serialize()函数中调用我们的myclass对象的Serialize函数就可以永久保存myclass对象了:


IMPLEMENT_DYNCREATE(C***Doc, CDocument)
BEGIN_MESSAGE_MAP(C***Doc, CDocument)
END_MESSAGE_MAP()
IMPLEMENT_SERIAL(MyClass,CObject,1);
void C***Doc::Serialize(CArchive& ar)
{
 if (ar.IsStoring())
 {
   myclass.Serialize(ar);
 }
 else
 {
   myclass.Serialize(ar);
 }
}


如何触发Serialize


当我们新建一个基于文档的MFC程序时,向导会自动为我们创建一些菜单,点击菜单的保存或者打开文件按钮时,内部机制自动触发Serialize函数调用,那么怎样在程序中自己触发Serialize呢?


剖开文件保存和打开内部机制(详见深入浅出MFC),对于读取文件,会得到类似这样的调用来触发Serialize加载机制:


CFileException fe;
CFile *pFile=GetFile("d://file.txt",
              CFile::modeRead | CFile::shareDenyWrite,
              &fe);
DeleteContents();
SetModifiedFlag();
CArchive loadArchive(pFile,CArchive::load );
loadArchive.m_pDocument=this;
loadArchive.m_bForceFlat=FALSE;
CWaitCursor wait;
if(pFile->GetLength()!=0)
   Serialize(loadArchive);
loadArchive.Close();
ReleaseFile(pFile,FALSE);


类似的,可以使用下面的操作来触发Serialize保存机制:


CFileException fe;
CFile *pFile=GetFile("d://file.txt",CFile::modeCreate|
         CFile::modeWrite | CFile::shareDenyWrite,
         &fe);
DeleteContents();
SetModifiedFlag();
CArchive saveArchive(pFile,CArchive::store );
saveArchive.m_pDocument=this;
saveArchive.m_bForceFlat=FALSE;
CWaitCursor wait;
if(pFile->GetLength()!=0)
Serialize(saveArchive);
saveArchive.Close();
ReleaseFile(pFile,FALSE);


相关文章
|
6月前
MFC消息映射机制
MFC消息映射机制
50 0
|
5月前
|
安全 Java 开发者
技术心得:反序列化Gadget学习篇五CommonCollections3
技术心得:反序列化Gadget学习篇五CommonCollections3
|
6月前
|
vr&ar
MFC序列化及反序列化对象
MFC序列化及反序列化对象
47 0
|
6月前
|
vr&ar
MFC序列化及反序列化变量
MFC序列化及反序列化变量
44 0
|
Dubbo Java 应用服务中间件
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
再谈序列化之rpc调用失败和jackson序列化时不允许Map中的key为null
237 0
|
编译器 API C++
C++通过LoadLibrary的方式调用C封装的dll
C++通过LoadLibrary的方式调用C封装的dll
890 0
C++通过LoadLibrary的方式调用C封装的dll
|
C++
将MFC Grid control封装为DLL的做法及其在DLL中的使用方法
MFCGrid control是一款非常优秀的网格控件,支持非常丰富的界面元素,如下图:   因而在数据库程序及报表程序应用较为广泛,其源码可以在下面下载到: MFC Grid control2.27源码下载        MFC Gridcontrol的作者并没有将其封装为DLL,因为在程序的多个模块复用这个控件比较麻烦(需要在多个工程中加入其源码),因此最好将其封装为一个DLL。
1713 1
DLL(MFC)通过Window消息向C#程序传递数据
这是我在用C#开发IOServer遇到的一个问题,该程序需要用到原先用MFC开发的DLL,最大问题是该dll运行过程中的一些信息,通过window消息向指定的hwnd(窗体句柄)发送数据。数据的指针放在WParam参数里,LParam参数是数据的类型信息。
855 0