孙鑫VC++视频教程笔记(13)文档与串行化_double强制转换成float-程序员宅基地

技术标签: 文档  VC++深入讲解(孙鑫)  file  function  vc++  mfc  microsoft  

把文件在磁盘上保存下来 叫做串行化
可以使用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);
在BOOL CGraphicDoc::OnNewDocument()中,我们可以设置文档,例如:
 SetTitle("SongPeng")
 
OnNewDocument()用来在程序运行之初构造文档,或是新建文档:
Called by the framework as part of the File New command. The default implementation of this function calls the DeleteContents member function to ensure that the document is empty and then marks the new document as clean. Override this function to initialize the data structure for a new document. You should call the base class version of this function from your override.

我们已可以在String Table中修改标题,其中的IDR_MAINFRAME中的字串原为:
Graphic/n/nGraphi/n/n/nGraphic.Document/nGraphi Document
各子串之间用/n分割,可以有空子串。
各子串定义如下:
CDocTemplate::windowTitle   Name that appears in the application window’s title bar (for example, “Microsoft Excel”). Present only in the document template for SDI applications.


CDocTemplate::docName   Root for the default document name (for example, “Sheet”). This root, plus a number, is used for the default name of a new document of this type whenever the user chooses the New command from the File menu (for example, “Sheet1” or “Sheet2”). If not specified, “Untitled” is used as the default.


CDocTemplate::fileNewName   Name of this document type. If the application supports more than one type of document, this string is displayed in the File New dialog box (for example, “Worksheet”). If not specified, the document type is inaccessible using the File New command.


CDocTemplate::filterName   Description of the document type and a wildcard filter matching documents of this type. This string is displayed in the List Files Of Type drop-down list in the File Open dialog box (for example, “Worksheets (*.xls)”). If not specified, the document type is inaccessible using the File Open command.


CDocTemplate::filterExt   Extension for documents of this type (for example, “.xls”). If not specified, the document type is inaccessible using the File Open command.


CDocTemplate::regFileTypeId   Identifier for the document type to be stored in the registration database maintained by Windows. This string is for internal use only (for example, “ExcelWorksheet”). If not specified, the document type cannot be registered with the Windows File Manager.


CDocTemplate::regFileTypeName   Name of the document type to be stored in the registration database. This string may be displayed in dialog boxes of applications that access the registration database (for example, “Microsoft Excel Worksheet”).

在前两个/n之间加入字符串,就达到修改标题的效果。

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

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

新建文档运行路径:
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()

CWinApp负责管理文档管理器

打开文档运行路径
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)

生成可串行化的类:
 A serializable class usually has a Serialize member function, and it usually uses the DECLARE_SERIAL and IMPLEMENT_SERIAL macros, as described under class CObject.
分为五步:
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.
IMPLEMENT_SERIAL(CGraph,CObject,1),1为版本号,保存和读取时版本号必须相同
一个文档类对象能和多个视类对象相关,一个视类对象只和一个文档类对象相关.

单文档类只有一个视类对象,要获取视类对象的指针
要在文档类中访问定义在视类中的对象,首先要获得视类的指针.需要用到函数
CDocument::GetFirstViewPosition 得到视类对象的位置
virtual POSITION GetFirstViewPosition( ) const;
A POSITION value that can be used for iteration with the GetNextView member function.
Call this function to get the position of the first view in the list of views associated with the document.
然后再调用GetNextView得到视类对象的指针
 POSITION pos=GetFirstViewPosition();
 CGraphicView *pView=(CGraphicView *)GetNextView(pos);

POSITION   A value used to denote the position of an element in a collection; used by MFC collection classes.

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

void CGraph::Serialize(CArchive &ar)
{
 if(ar.IsStoring())
 {
  ar<<m_nDrawType<<m_pOrigin<<m_pEnd;
 }
 else
 {
  ar>>m_nDrawType>>m_pOrigin>>m_pEnd;
 }
}

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;
  CGraph *pGraph;
  for(int i=0;i<nCount;i++)
  {
   ar>>pGraph;
   pView->m_obArray.Add(pGraph);
  }
 }
}

数组的保存:
 CGraph *pGraph=new CGraph(m_nDrawType,m_pOrigin,point);
 m_obArray.Add(pGraph);

CObArray incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its elements. If an array of CObject pointers is stored to an archive, either with the overloaded insertion operator or with the Serialize member function, each CObject element is, in turn, serialized along with its array index
void CGraphicDoc::Serialize(CArchive& ar)可被修改为:
void CGraphicDoc::Serialize(CArchive& ar)
{
 POSITION pos=GetFirstViewPosition();
 CGraphicView *pView=(CGraphicView *)GetNextView(pos);
 if (ar.IsStoring())
{
}
else
{
}
pView->m_obArrary.Serialize(ar);
}

以下是CObArray在MFC中的源代码:
void CObArray::Serialize(CArchive& ar)
{
 ASSERT_VALID(this);

 CObject::Serialize(ar);

 if (ar.IsStoring())
 {
  ar.WriteCount(m_nSize);
  for (int i = 0; i < m_nSize; i++)
   ar << m_pData[i];
 }
 else
 {
  DWORD nOldSize = ar.ReadCount();
  SetSize(nOldSize);
  for (int i = 0; i < m_nSize; i++)
   ar >> m_pData[i];
 }
}

文档类时用来管理数据的我们把CObArray m_obArray放入文档类中
以下为自动生成类,这是在View类中准备好的可以获得文档来指针的函数:
CGraphicDoc* CGraphicView::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGraphicDoc)));
 return (CGraphicDoc*)m_pDocument;
}

 在View中可以这样调用m_obArray
CGraphicDoc *pDoc=GetDocument();
 pDoc->m_obArray.Add(pGraph);

Document/View结构
在MFC中,文档类负责管理数据,提供保存和数据加载的功能。视类负责数据的显示,以及给用户提供对数据的编辑和修改功能。
MFC给我们提供Document/View结构,将一个应用程序所需要的数据处理与显示的函数的空壳都设计好了,这些函数都是需函数,我们可以在派生类中重写这些函数。有关文件读写的操作在CDocument的Serialize函数中进行,有关数据和图形显示的操作在CView的OnDraw函数中进行。我们在其派生类中,只需要去关注serialize和OnDraw函数就可以了,其他的细节我们不需要去理会,程序就可以良好的运行。
当我么按下"File/Open",Application Framework会激活文件打开对话框,让你指定文件名,然后自动调用CGraphicView::OnDraw,传递一个显示DC,让你重新绘制窗口内容。
MFC给我们提供Document/View结构,是希望我们将精力放在数据结构的设计和数据显示的操作上,而不是把时间和精力花费在对象与对象之间,模块与模块之间的通信上。
一个文档对象可以和多个视类对象相关联,而一个视类对象只能和一个文档类对象相关联

不管是新建文档还是打开另外一份文档,都会调用DeletContents,以保证新建文档时空的

释放对内存
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();
}
CDocument::DeleteContents()会在打开,新建,关闭文档时被调用

CObArray::RemoveAt
Removes one or more elements starting at a specified index in an array. In the process, it shifts down all the elements above the removed element(s). It decrements the upper bound of the array but does not free memory.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);
 }

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/GoOnDrift/article/details/5399535

智能推荐

[常用办公软件] wps怎么自动生成目录?wps自动生成目录的设置教程_wps目录自动生成-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏5次。转载请说明来源于"厦门SEO"本文地址:http://www.96096.cc/Article/160880.html常用办公软件  WPS Office是由金山软件股份有限公司开发的一款针对个人永久免费的办公软件,在我们的日常生活和工作中,WPS Office比起微软Microsoft Office来说在文字上的处理会更深入国人用户的人心,熟悉操作WPS的办公小技巧,能够更高效的提高我们的工作效率,今天小编要为大家分享的是WPS怎么自动生成目录?快来一起看看WPS自动生成目录的设置教程吧。_wps目录自动生成

web项目-程序员宅基地

文章浏览阅读7.4k次,点赞2次,收藏19次。web项目是指服务端部署在服务器上,客户端使用浏览器通过网络传输进行访问获取数据的项目。通常我们看见的应用页面网站等等都可以称之为web项目。 在web项目的开发中可分为web前端开发和web后端开发 web前端:即是客户端能看得见碰得着得东西。包括Web页面结构、页面样式外观以及Web层面得交互展现。 前端特点:页面视觉效果良好(客户第一)、Web页面交互流畅(..._web项目

关于java操作excel导入导出三种方式_java导出excel的三种方法-程序员宅基地

文章浏览阅读5.6k次,点赞8次,收藏67次。java操作关于导入导出Excel的多种方式_java导出excel的三种方法

Windows系统环境变量path详解_windows path-程序员宅基地

文章浏览阅读1.1w次,点赞10次,收藏21次。Windows path系统变量编辑_windows path

Hadoop基础教程-第13章 源码编译(13.2 Hadoop2.7.3源码编译)_hadoop2.7.3-src源码下载-程序员宅基地

文章浏览阅读512次。第13章 源码编译13.2 Hadoop2.7.3源码编译13.2.1下载Hadoop源码包(1)到官网http://hadoop.apache.org/releases.html下载2.7.3的source源码包(2)解压缩tar -zxvf hadoop-2.7.3-src.tar.gz -C /opt1(3)打开解压目录下的BUILDING.txt,编译过程和需要的软件其实就是根据这个文档里..._hadoop2.7.3-src源码下载

Latex 语法_\latex-程序员宅基地

文章浏览阅读1k次。Latex 语法_\latex

随便推点

【智能排班系统】基于AOP和自定义注解实现接口幂等性-程序员宅基地

文章浏览阅读884次。使用多种方式实现接口幂等性,通过定义注解方便对方法进行幂等性控制

SpringBoot整合Swagger2 详解_springboot swagger2 开关-程序员宅基地

文章浏览阅读324次。SpringBoot、Swagger2 整合详解_springboot swagger2 开关

spring boot 项目报错 java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized_springboot项目里面报错 the server time zone value ' й-程序员宅基地

文章浏览阅读2.8w次,点赞96次,收藏115次。报错说是时区不对因为mysql-connection-java版本导致时区的问题。pom.xml:控制台报错信息:java.sql.SQLException: The server time zone value ‘�й���׼ʱ��’ is unrecognized or represents more than one time zone. You must configure ei..._springboot项目里面报错 the server time zone value ' й

最全Android Kotlin 学习路线(Kotlin 从入门、进阶到实战)_kotlin学习-程序员宅基地

文章浏览阅读4.2k次。Kotlin 是由 jetBrains 开发的一门现代多平台应用的静态编程语言,Kotlin 代码即可以编译成 Java 字节码,又可以编译成 JavaScript,Kotlin 是开源的,源码在这。Kotlin 包含了大量的语法糖,在编码的时候,会大大的简化我们的代码量及工作效率。且相比传统的 Java 语言,Kotlin 种大量的简写,可以减少很多用Java 必须要写的样板代码,减少大量的 if…else 等嵌套,减少大量接口的实现,代码结构也会更加清晰。_kotlin学习

【前端素材】推荐优质新鲜绿色蔬菜商城网站设计Harmic平台模板(附源码)-程序员宅基地

文章浏览阅读753次,点赞30次,收藏21次。在线绿色新鲜果蔬商店网站是指一个专门销售新鲜、绿色、有机水果和蔬菜的电子商务平台。这类网站旨在为消费者提供方便、快捷的购买渠道,同时确保他们能够购买到高质量、新鲜的产品。

elementui表格添加fixed之后样式异常_element table fixed 样式异常-程序员宅基地

文章浏览阅读1k次。最近写项目碰到一个bug 大概就是一个表格组件两个页面都会使用 组件中表格的某些列就用v-if控制了 表格的首尾列都用了fixed 然后就发生了bug 如下图 具体原因不明看过很多网上的办法 有在fixed的列绑定key的 也有使用doLayout()的 测了都没用 最后在一个前端交流群里一位大佬给出的办法 实测有效.el-table__header, .el-table__body, .el-table__footer { width: 100%; tab_element table fixed 样式异常

推荐文章

热门文章

相关标签