在程序中使用CArchive对象时有几点需要注意,首先是在创建CArchive对象之前必须先创建一个CFile或
其派生类对象,并且因为存档对象既可以用来加载数据,也可以用来保存数据,所以必须确保这个CFile
类对象的打开方式与该文档对象的加载/保存状态相一致。当构造了一个CArchive对象后,就可以将它与
一个代表某个打开文件的CFile类对象或派生类对象相关联。但是一个文件只能与一个活动的存档对象相
关联。
读写文件操作:
void CGraphicView::OnFileWrite()
{
CFile file(_T( "1.txt" ), CFile::modeCreate | CFile::modeWrite);
CArchive ar( &file , CArchive::store);
int i = 4;
TCHAR ch = 'a';
float f = 1.3f;
CString str( _T("http://www.sunxin.org, lalor , test"));
ar<< i << ch << f << str;
}
void CGraphicView::OnFileRead()
{
CFile file(_T( "1.txt") , CFile::modeRead);
CArchive ar( &file , CArchive::load);
int i ;
char ch;
float f;
CString str;
CString strResult;
ar >> i >> ch >> f >> str;
strResult.Format( " %d %c %f %s" , i , ch , f, str );
MessageBox( strResult);
}
CDOCUMENT的OnNewDocument成员函数:
当打开应用程序是会调用该函数,File/New是也会调用该函数
修改新建文档的标题就在该函数中:
SetTitle( "lalor");
当保存数据时,先前创建的文档类的对象就与该数据关联在一起了,表示了该数据。当再次打开刚保存
的文件时,在MFC架构内部,它判断出这事同一份数据,并且和这个数据相关联的文档类对象相关联的指
针已经存在了,它就不会再去调用文档类的Seriali
ze函数了。
【文件/新建】和【文件/打开】菜单项的命令响应函数都是在CWinApp类中提供的。CWinApp类有一个成
员变量:m_pDocManager,是指向CDocManager对象的指针,也就是说,CWinApp负责管理文档管理器,而
后者有一个文档模板指针链表:m_templateList,用来保存文档模板的指针,即文档管理器负责管理文
档模板,而后者又是用来管理文档类、架构类和视类的,始终让这三个对象三位一体一起为文档服务。
一个可串行化的类通常都有一个Serialize成员函数。成果要使一个类可串行化,可以经过一下五个步骤
来实现:
①从CObject派生类
②重写Serialize成员函数
③使用DECLARE_SERIAL宏
④定义不带参数的构造函数
⑤为类在实现文件中使用IMPLEMENT_SERIAL宏
保存画图程序的实现步骤:
①构造一个CGraphic类,用以保存图形
②在视类中添加一个容器(CObArray类)用以保存任意多个CGraphic对象
③保存的时候,系统自动调用文档类的Serialize成员函数,需要在该成员函数中获取视类对象。在保存
对象时自动调用CGraphic类的Serialize,将CGraphic类的个成员变量依次保存起来。
形如:
void CGraphicDoc::Serialize(CArchive& ar)
{
POSITION pos = GetFirstViewPosition();
CGraphicView *pView = (CGraphicView*)GetNextView(pos);
if (ar.IsStoring())
{
int nCount = pView->m_obArray.GetSize();
ar << nCount;
for( int i = 0; i < nCount ; i++ )
{
ar << pView->m_obArray.GetAt(i);
}
}
else
{
int nCount;
ar >> nCount;
Graphic *pGraphic;
for( int i = 0; i < nCount ; i++ )
{
ar >> pGraphic;
pView->m_obArray.Add( pGraphic);
}
}
CObArray类也支持串行化,所以可以在if、else外调用pView->m_obArray.Seriallize(ar);
在CGraphicView类的GetDocument函数的返回值就是CGraphicDoc类的指针,也就是说,视类中已经为我
们准备好了可以获得文档类指针的函数,可以直接获得指向文档类对象的指针。
}
对于一个文档类对象来说,可以有多个视类对象与之相关。但对于一个视类对象来说,它只能与一个文
档类对象相关。因此,为了获得与文档对象相关的视类对象,首先就要通过CDocument类的
GetFirstViewPosition成员函数获得与该文档对象相关的视类链表中第一个视类对象的位置,然后通过
GetNextView函数得到当前位置所指示的视类对象指针。
DeleteContents函数是一个虚函数,主要是由架构调用,用来删除文档的数据,同时并不销毁CDocument
对象本身。他是在文档将要被销毁之前被调用,也会在该文档对象在重复使用之前被调用,以确保文档
是空的。
VC++深入详解之第十三章文档和串行化笔记
