博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC的Serialize机制及其使用(转)
阅读量:4302 次
发布时间:2019-05-27

本文共 3222 字,大约阅读时间需要 10 分钟。

1. OnNewDocument()调用过程:

  程序启动->CWinApp:;OnFileNew(m_pDocManager->OnFileNew()) ->CDocManager::OnFileNew(pTemplate->OpenDocumentFile(NULL)) ->CSingleDocTemplate::OpenDocumentFile(CreateNewDocument->CreateNewFrame     pDocument->OnNewDocument) -> CGraphicDoc::OnNewDocument

2.Serialize()调用过程

文件打开菜单命令->CWinApp::OnFileOpen(m_pDocManager->OnFileOpen()) ->CDocManager::OnFileOpen(调用DoPromptFileName函数显示文件打开对话框->AfxGetApp()->OpenDocumentFile) ->CWinApp::OpenDocumentFile(m_pDocManager->OpenDocumentFile) ->CDocManager::OpenDocumentFile ->CSingleDocTemplate::OpenDocumentFile(pDocument->OnOpenDocument) ->CDocument::OpenDocument(构造一个CFile::modeRead模式的Cfile对象-》构造一个CArchive::load模式的CArchive对象-》Serialize(loadArchive))->CGraphicDoc::Serialize

 

 [文件\新建]和【文件\打开】菜单项的命令响应函数都是在CWinApp类中提供的。CWinApp类有一个成员变量:m_pDocManager,是指向CDocManager对象的指针,也就是说,CWinApp负责管理文档管理器,而后者有一个文档模板指针链表:m_templateList,用来保存文档模板的指针,即文档管器负责管理文档模板,而后者又是用来管理文档类、框架类和视类的,始终让这三个对象三位一体,一起为文档服务。

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

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

一个类要支持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);

转:

转载地址:http://hcmws.baihongyu.com/

你可能感兴趣的文章
Linux常用命令002之搜索命令locate、whereis、which、find、grep
查看>>
oop_day03_内存管理、引用类型数组
查看>>
Java小游戏之打飞机(二)
查看>>
oop_day04_继承、重写_20150812
查看>>
Java笔试面试题006
查看>>
oop_day05_package、public、static、final、内部类
查看>>
oop_day06_抽象类、接口_20150814
查看>>
Java笔试面试题007
查看>>
Java 抽象类与接口的区别
查看>>
oop_day07_多态_20150815
查看>>
Java笔试面试题008
查看>>
Java之面向对象详细总结
查看>>
Java笔试面试题009
查看>>
Java笔试面试题010
查看>>
【JavaSE】day01_ API文档 、 字符串基本操作
查看>>
写给java程序员的一封情书
查看>>
【JavaSE】day02_正则表达式 、 Object 、 包装类
查看>>
【Java】Java小游戏之Shoot游戏源码及详解
查看>>
【JavaSE】day03_Date、SimpleDateFormat、Calendar、Collection
查看>>
【JavaSE】day04_Collection_Iterator_新循环_泛型
查看>>