第十三课

使用CArchive类对文件进行操作。MFC框架程序提供的文件新建与打开功能内部的实现机制。如何利用CDocument类的串行化存储功能保存与加载数据。如何实现类对串行化的支持,CObArray的串行化实现内幕。删除文档数据时常犯的错误。MFC框架程序的文档类和视类的关系,以及如何获得相互的指针引用。

 
  
  1. CArchive类 
  2. 写入 
  3. void CGraphicView::OnFileWrite()  
  4.     // TODO: Add your command handler code here 
  5.     CFile file("1.txt",CFile::modeCreate | CFile::modeWrite);首先要创建一个CFile 对象 
  6.     CArchive ar(&file,CArchive::store); 
  7.     int i=4; 
  8.     char ch='a'
  9.     float f=1.3f;      浮点数缺省为double,所以要加f  
  10.     CString str("http://www.sunxin.org"); 
  11.     ar<<i<<ch<<f<<str; 
  12. 读取 
  13. void CGraphicView::OnFileRead()  
  14.     // TODO: Add your command handler code here 
  15.     CFile file("1.txt",CFile::modeRead); 
  16.     CArchive ar(&file,CArchive::load); 
  17.     int i; 
  18.     char ch; 
  19.     float f; 
  20.     CString str; 
  21.     CString strResult; 
  22.     ar>>i>>ch>>f>>str; 
  23.     strResult.Format("%d,%c,%f,%s",i,ch,f,str); 
  24.     MessageBox(strResult); 
  25.  
  26. 设置文档标题,这个函数在文档启动的时候调用 
  27. BOOL CGraphicDoc::OnNewDocument() 
  28.     if (!CDocument::OnNewDocument()) 
  29.         return FALSE; 
  30.  
  31.     // TODO: add reinitialization code here 
  32.     // (SDI documents will reuse this document) 
  33. //  SetTitle("http://www.sunxin.org"); 

String TableIDR_MAINFRAME字符串资源中各子串的含义

(1)CDocTemplate::windowTitle,主窗口标题栏上的字符串,MDI程序不需要指定,将以IDR_MAINFRAME字符串为默认值。

(2)CDocTemplate::docName,缺省文档的名称。如果没有指定,缺省文档的名称是无标题。

(3)CDocTemplate::fileNewName,文档类型的名称。如果应用程序支持多种类型的文档,此字符串将显示在"File/New"对话框中。如果没有指定,就不能够在"File/New"对话框处理这种文件。

(4)CDocTemplate::filterName,文档类型的描述和一个适用于此类型的通配符过滤器。这个字符串将出现在“File/Open”对话框中的文件类型列表框中。要和CDocTemplate::filterExt一起使用。

(5)CDocTemplate::filterExt,文档的扩展名。如果没有指定,就不能够在“File/Open”对话框中处理这种文档。要和CDocTemplate::filterName一起使用。

(6)CDocTemplate::regFileTypeId,如果你以::RegisterShellFileTypes向系统的注册表注册文件类型,此值会出现在HEY_CLASSES_ROOT之下成为其子项,并仅供Windows内部使用。如果没有指定,这种文件类型就无法注册。

(7)CDocTemplate::regFileTypeName,这也是存储在注册表中的文件类型名称。它会显示于程序中用以访问注册表的对话框内。

Document/View结构

MFC中,文档类负责管理数据,提供保存和加载数据的功能。视类负责数据的显示,以及给用户提供对数据的编辑和修改功能。

MFC给我们提供Document/View结构,将一个应用程序所需要的“数据处理与显示”的函数空壳都设计好了,这些函数都是虚函数,我们可以在派生类中重写这些函数。有关文件读写的操作在CDocumentSerialize函数中进行,有关数据和图形显示的操作在CViewOnDraw函数中进行。我们在其派生类中,只需要去关注SerializeOnDraw函数就可以了,其它的细节我们不需要去理会,程序就可以良好地运行。

当我们按下“File/Open”,Application Framework会激活文件打开对话框,让你指定文件名,然后自动调用CGraphicDoc::Serialize读取文件。Application Framework还会调用CGraphicView::OnDraw,传递一个显示DC,让你重新绘制窗口内容。

MFC给我们提供Document/View结构,是希望我们将精力放在数据结构的设计和数据显示的操作上,而不要把时间和精力花费在对象与对象之间、模块与模块之间的通信上。

一个文档对象可以和多个视类对象相关联,而一个视类对象只能和一个文档对象相关联。

CGraphicDoc::Serialize(CArchive& ar)

 

 
  
  1. 文档类有个专门的CArchive类操作。 
  2. void CGraphicDoc::Serialize(CArchive& ar) 
  3.     POSITION pos=GetFirstViewPosition();得到第一个视类位置 
  4.     CGraphicView *pView=(CGraphicView*)GetNextView(pos);得到下一个 
  5.     if (ar.IsStoring()) 
  6.     { 
  7.         // TODO: add storing code here 
  8. /*      int i=5; 
  9.         char ch='b'; 
  10.         float f=1.2f; 
  11.         CString str("http://www.sunxin.org"); 
  12.         ar<<i<<ch<<f<<str;*/ 
  13. /*      int nCount=pView->m_obArray.GetSize(); 
  14.         ar<<nCount; 
  15.         for(int i=0;i<nCount;i++) 
  16.         { 
  17.             ar<<pView->m_obArray.GetAt(i); 
  18.         }*/ 
  19.     } 
  20.     else 
  21.     { 
  22.         // TODO: add loading code here 
  23.         /*int i; 
  24.         char ch; 
  25.         float f; 
  26.         CString str; 
  27.         CString strResult; 
  28.         ar>>i>>ch>>f>>str; 
  29.         strResult.Format("%d,%c,%f,%s",i,ch,f,str); 
  30.         AfxMessageBox(strResult);*/ 
  31. /*      int nCount; 
  32.         ar>>nCount; 
  33.         CGraph *pGraph; 
  34.         for(int i=0;i<nCount;i++) 
  35.         { 
  36.             ar>>pGraph; 
  37.             pView->m_obArray.Add(pGraph); 
  38.         }*/ 
  39.     } 
  40. //  pView->m_obArray.Serialize(ar); 
  41.     m_obArray.Serialize(ar);