文档与串行化笔记—孙鑫(转)

文档与串行化笔记—孙鑫(转)

转自:http://blog.csdn.net/peng6662001/archive/2006/03/29/642366.aspx(稍作修改)

 

串行化概念

把文件在磁盘上保存下来 叫做串行化

 

使用CArchive
写入:

 CFile file("1.txt",CFile::modeCreate | CFile::modeWrite);

 CArchive ar(&file,CArchive::store);

int i=4;
 float b=1.3f;   //C
默认用float定义而不加f的为double

 CString str="SongPeng";
 ar<<i<<b<<str;

 

读取:

 

 CFile file("1.txt",CFile::modeRead);
 CArchive ar(&file,CArchive::load);
 int i;
 float b;
 CString str;
 CString strRestult;
 ar>>i>>b>>str;
 strRestult.Format("%d %f %s",i,b,str);
 MessageBox(strRestult);

 

设置文档标题的三种方法:

l        BOOL CGraphicDoc::OnNewDocument()中,我们可以设置文档,例如:
 SetTitle("SongPeng")

l        我们也可以在String TableIDR_MAINFRAME第二个标题,

l        在新建工程的第四部advance选项中也能进行修改

IDR_MAINFRAME

其中的IDR_MAINFRAME中的字串各子串之间用/n分割,可以有空子串。
各子串定义如下:
CDocTemplate::windowTitle  
CDocTemplate::docName  

CDocTemplate::fileNewName  

CDocTemplate::filterName  
CDocTemplate::filterExt  
CDocTemplate::regFileTypeId  
CDocTemplate::regFileTypeName  

 

小知识点:凡是从CCmdTarget派生出的类,都可以间接接受命令消息

生成可串行化的类:
分为五步:

l        CObject的派生类

l        重写Serialize函数

l        在声明(*.h)中使用DECLARE_SERIAL(class_name)

l        定义无参数的构造函数

l        实现(*.cpp)中使用IMPLEMENT_SERIAL
参考:IMPLEMENT_SERIAL(CGraph,CObject,1),1为版本号,保存和读取时版本号必须相同

 

在文档类中获得视图类的指针

例子:

 

POSITION pos=GetFirstViewPosition();

//pos是下一个视图的指针,若无,则返回NULL
 CGraphicView *pView=(CGraphicView *)GetNextView(pos);

我们文档类中调用Serialize保存一个可串行化的类的数据时实际上是利用了这个对象本身的Serialize函数,这个对象需要什么对象,都需要在你编写可串行化的类时去确定

 

CObArray保存CObject派生类:

特点:

l        支持串行化

l        常作为文档类的成员(视图类中调用GetDocument()函数)

示例代码:

 

CGraph *pGraph=new CGraph(m_nDrawType,m_pOrigin,point);
 m_obArray.Add(pGraph);

 

注意:删除CobArray元素的时候,因为CobArray保存的指针,所以首先应该delete指针指向的对内存,然后在remove指针元素。不管是新建文档还是打开另外一份文档,都会调用DeletContents,以保证新建文档时空的,CDocument::DeleteContents()会在打开,新建,关闭文档时被调用

 

void CGraphicDoc::DeleteContents()
{
 // TODO: Add your specialized code here and/or call the base class
 int nCount;
 nCount=m_obArray.GetSize();
 for(int i=0;i<nCount;i++)
 {
  delete m_obArray.GetAt(i);  //
解除指针与值之间的联系,但没有清除堆内存

  m_obArray.RemoveAt(i);  //
清除堆内存,出错!!!
 }
 CDocument::DeleteContents();
}

 

RemoveAt会导致数组中数据的重排
因此,需要把以上代码修改为

 

void CGraphicDoc::DeleteContents()
{
 // TODO: Add your specialized code here and/or call the base class
 int nCount;
 nCount=m_obArray.GetSize();
 for(int i=0;i<nCount;i++)
 {
  delete m_obArray.GetAt(i);
 }
 m_obArray.RemoveAll();
 CDocument::DeleteContents();
}

 

另一种方法

 

 while (nCount--)
 {
  delete m_obArray.GetAt(nCount);
  m_obArray.RemoveAt(nCount);
 }

 

 

Document/View结构

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

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

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

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

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

视图文档类的交互:

文档类调用

UpdateAllViews(NULL);//更新所有此文档派生的视图;

视图类调用虚函数:

OnUpdate//更新数据

 

新建文档运行路径:
void CWinApp::OnFileNew()--->void CDocManager::OnFileNew()---> 
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();--->
pTemplate->OpenDocumentFile(NULL);--->CDocument*
CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
 BOOL bMakeVisible)--->pDocument = CreateNewDocument();
--->pFrame = CreateNewFrame(pDocument, NULL);--->
if (!pDocument->OnNewDocument())--->BOOL CGraphicDoc::OnNewDocument()

 

打开文档运行路径
void CWinApp::OnFileOpen()--->void CDocManager::OnFileOpen()--->
DoPromptFileName--->BOOL CDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)--->
打开一个文件--->AfxGetApp()->OpenDocumentFile(newName);--->
CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)--->
CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)--->
match = pTemplate->MatchDocType(szPath, pOpenDocument);--->
判断pOpenDocument是否为空,pOpenDocument用来指定是否与先前的文档关联,即获取先前相同文档的指针,如果是,不再对文档进行操作
---->
CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
 BOOL bMakeVisible)--->if (pDocument == NULL)--->if (pFrame == NULL)--->
if (lpszPathName == NULL)--->if (!pDocument->OnOpenDocument(lpszPathName))--->
BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)---->
Serialize(loadArchive);---->void CGraphicDoc::Serialize(CArchive& ar)

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值