在面向对象的程序设计中,一般都是用二进制文件来保存文档资料。在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件;利用串行化存取文件。其中用CFile对象直接存储文档,存在着以下两个问题:一是过程繁琐,例如绘图系统中常存在大量的数据对象(直线对象、矩形对象等);另一个问题是功能受限,VC++为了程序集成的需要,设汁成了复合文档,可以把各种外来对象(如OLE对象的嵌入和链接)的内容存储到外部文件中并从外部文件中读取内容更新构造对象,而程序的设计者并不知道这些对象中需要存储数据的内容和格式,在这种情况下,直接利用CFile类就无能为力了。
既然已决定采用串行化的方法,就要明确串行化的概念:CArchive类用于以持久的二进制形式(通常是磁盘存储)来存储一个复杂的对象网络,用户可以把对象的内容存储到存储区中,也可以从存储区中读取内容重新构造对象。这个过程成为“串行化”,下面介绍串行化的几个基础知识点:
1 CArchive。构造函数:CArchive( CFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL ),参数意义查阅MSDN。两个重要函数:IsStoring()和IsLoading(),以及>>和<<两个重载的操作符。
2 如何使自定义的类具有串行化功能呢?有以下五个步骤: 1)Deriving your class from CObject (or from some class derived from CObject). 2)Overriding the Serialize member function. 3)Using the DECLARE_SERIAL macro in the class declaration. 4)Defining a constructor that takes no arguments. 5)Using the IMPLEMENT_SERIAL macro in the implementation file for your class.
3 CObArray::Serialize()。CObArray类支持CObject类对象指针数组,它如同一个指针数组来管理直接或间接派生的CObject对象指针。当调用一个CObArray对象的Serialize()函数进行存储操作时,首先存储了数组的项数,然后循环对各个项目(各个对象)进行存储,进行了如下操作: 1)将对象的信息写入文件。包括类的信息;版本信息; 2)调用对象的Serialize成员函数,将对象的数据写入文件。 而当进行读取操作时,首先读取了存储数组的项目数,然后将数组的项目初始化成需要的项目数,然后进行如下操作: 1)从文件读取类的信息,动态生成相应类(CLine)的对象,存放对象的指针; 2)调用对象的Serialize()成员函数,从文件读取对象数据初始化新生成的对象。
4Document/View结构. 1)在MFC中,文档类负责管理数据,提供保存和加载数据的功能。视类负责数据的显示,以及给用户提供对数据的编辑和修改功能。
5 String Table中IDR_MAINFRAME字符串资源中各子串的含义. 1)CDocTemplate::windowTitle,主窗口标题栏上的字符串,MDI程序不需要指定,将以IDR_MAINFRAME字符串为默认值。
下面介绍用串行化实现文档存储与读写的步骤: 1 实现一个可串行化的类(五个步骤)。特别注意的是改写Serialize()函数;
2 修改String Table中IDR_MAINFRAME字符串资源中子串,使其符合自己需求;
3 在CMyDoc类中增加一个CObArray的成员变量;修改CMyDoc::Serialize();如果需要保存CMyView类中的数据成员,可以利用一下代码获取CMyView的指针:POSITION pos=GetFirstViewPosition(); CGraphicView *pView=(CGraphicView*)GetNextView(pos);
4 新建和打开文档时,要注意销毁原来的数据。在DOC的DeleteContents虚函数中是好时机。代码如下: } 还有一种方法: |
|