热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CDocument文档类

文档类本身并没有直接提供强大的功能实现,它只是提供了一个框架,为文档对象与相关的其他对象(视图、应用程序对象及框架窗口等)进
文档类本身并没有直接提供强大的功能实现,它只是提供了一个框架,为文档对象与相关的其他对象(视图、应用程序对象及框架窗口等)进行交互提供了框架。对文档部分的设计工作,基本上都是在这个已有框架的基础上,添加所需要的功能代码。

文档类(CDocument)在MFC类库中的层次结构如图4-3所示。


图4-3  CDocument在MFC类库中的层次结构

不管是SDI应用程序还是MDI应用程序,文档类都是从CDocument类派生出来的。
在文档/视图结构中,文档的主要任务通常是对数据库进行管理和维护,数据将保存在文档类的成员变量中,视图通过对这些变量的访问来获取或送回数据,并能通过这种方式来更新并显示数据。
文档还负责将数据存储到永久的存储介质中,通常是磁盘或数据库,这个存取过程称之为串行化。
此外,文档还可以处理来自菜单、工具栏、加速键等对象的命令消息(WM_ COMMAND)。除WM_COMMAND外,文档不能处理其他的Window消息。
1.数据的串行化
串行化是指将对象写入永久存储介质或者将对象从永久存储介质中读出的过程。
串行化的基本用法是使文档对象能够将自身的当前数据保存到存储介质,也能从存储介质中读取所保存的数据,并使用这些数据来重建对象。当用户将数据传递到文档时,对象应该知道如何将自身保存到文档并能从文档中读取、重建自身。
串行化操作是通过对文档类Serialize()函数进行重载来完成的,当使用AppWizard创建SDI或MDI应用程序框架时,将自动生成一个Serialize()函数重载的框架。
2.CArchive类和CFile类
CArchive类没有基类&#xff0c;CArchive对象类似于C&#43;&#43;中的标准输入/输出流&#xff0c;它提供了一组用于从文件读取数据和将数据写入文件的成员函数。可以使用“>>”和“<<”运算符像在C&#43;&#43;中一样进行数据的输入/输出。
与C&#43;&#43;的标准输入/输出流不同的是标准输入/输出流存取的是格式化的ASCII字符串&#xff0c;而CArchive存取的是二进制对象&#xff0c;这种格式更为有效&#xff0c;且用途广泛。
在使用“>>”和“<<”运算符时&#xff0c;CArchive对象将作为运算符的第一操作数据&#xff0c;表4-1给出了所支持的第二操作数据的数据类型。

在创建CArchive类对象前&#xff0c;必须创建一个CFile对象&#xff0c;并将其与CArchive对象相关联。在文档/视图结构的实现中&#xff0c;这一步将由框架在调用Serialize()函数前自动完成。
在使用AppWizard创建的文档中&#xff0c;当单击打开或保存菜单项时&#xff0c;程序将自动创建一个指定文件的CFile对象&#xff0c;再创建一个指向该对象的CArchive对象&#xff0c;将二者都置为相同状态——打开或保存&#xff0c;然后再调用文档类Serialize()函数&#xff0c;将数据写入CArchive对象或从CArchive对象读取数据。当Serialize()函数完成工作后&#xff0c;框架将先后自动销毁CArchive对象和CFile对象。
如果要显示创建自己的CArchive对象&#xff0c;可以先创建一个CFile对象&#xff0c;然后构造一个CArchive对象&#xff0c;并将CFile对象通过CArchive类的构造函数传递给CArchive对象。CArchive类的构造函数原型如下&#xff1a;

CArchive( CFile* pFile, UINT nMode, int nBufSize &#61; 4096, void* lpBuf &#61; NULL );


参数pFile为CFile对象的指针&#xff1b;参数nMode是一个标识&#xff0c;它指定了对象的打开方式&#xff1b;参数nBufSize指定内部文件缓冲区的整数大小&#xff0c;以字节计算&#xff0c;默认大小为4096字节&#xff1b;lpBuf是指向nBufSize大小提供的缓冲区的指针。
3&#xff0e;文档与视图的交互
每一种类型的文档都有与之对应的文档模板进行管理&#xff0c;文档模板负责创建和管理当前类型的所有文档&#xff0c;文档与文档关联的视图和与视图关联的框架窗口都由文档模板所创建。
程序框架提供了两个文档模板类&#xff1a;CSingleDocTemplate和CMultiDocTemplate&#xff0c;分别用于支持SDI应用程序和MDI应用程序。
SDI应用程序一次只能使用一种类型的文件&#xff0c;如Windows中的画图、记事本等。
MDI应用程序则可以同时使用多种类型的文件&#xff0c;如Word、Excel等。
【实例4-1】  文档的存取
光盘路径   /04/CDocument
实例目的   使用串行化保存读取文件
这个实例用来说明如何使用串行化保存读取文件。文件名为CDocument。
&#xff08;1&#xff09;创建工程
在IDE中依次选择“File”→“New”菜单命令&#xff0c;或直接按快捷键“Ctrl&#43;N”&#xff0c;打开“New”对话框。
在“New”对话框中单击“Projects”选项卡&#xff0c;在列表框中选择“MFC AppWizard&#xff08;.exe&#xff09;”项&#xff0c;在“Project name”文本框中输入“CDocument”&#xff0c;其他使用默认值&#xff0c;单击“OK”按钮&#xff0c;弹出“MFC AppWizard-Step1”对话框。
在“MFC AppWizard-Step1”对话框中&#xff0c;选中“Single Document”单选框&#xff0c;其他使用默认值&#xff0c;然后单击“Finish”按钮&#xff0c;在弹出的“New Project Information”对话框中单击“OK”按钮&#xff0c;就可以完成工程的创建。
在工作区中选择的Resource View标签&#xff0c;转到资源编辑窗口&#xff0c;单击“String Table”→“String Table”条目&#xff0c;打开串表编辑器。找到ID为IDR_MAINFRAME的现有字符串&#xff0c;双击打开串表的属性对话框&#xff0c;并对它进行修改&#xff0c;该字符决定了应用程序所创建的文档类型。将字符串内容改为“CDocument\n\nCDoc\nMyDoc(*.mdc)\n.mdc\nCDocument.Document\n \nCDocDocument\n”&#xff0c;如图4-4所示。


图4-4  修改文档类型字符串

&#xff08;2&#xff09;添加响应函数
在IDE主菜单项中依次选择“View”→“ClassWizard”&#xff0c;打开MFC ClassWizard对话框&#xff0c;选择“Member Maps”选项卡&#xff0c;在“Project”下拉列表框中选择CDocument&#xff0c;在“Class name”下拉列表框中选择“CCDocument View”。
在“Object IDs”下拉列表框中选择CCDocument View&#xff0c;在Message项中选中消息WM_CHAR。
单击“Add Function…”按钮&#xff0c;添加函数消息&#xff0c;单击“OK”按钮就可以创建一个名称为OnChar的消息处理函数&#xff0c;单击“Edit Code”按钮退出“ClassWizard”对话框&#xff0c;并自动打开CDocument View.cpp文件&#xff0c;且定位在OnChar()函数上。
用同样的步骤添加另一个消息&#xff0c;消息名为OnInitialUpdate。添加完成后的MFC ClassWizard对话框如图4-5所示。


图4-5 “MFC ClassWizard”对话框

&#xff08;3&#xff09;添加变量
通过工作区中的ClassView标签&#xff0c;CCDocument View类中添加一个CString类数据成员m_str&#xff0c;其步骤如下&#xff1a;右键单击“CCDocument classes”→“CCDocument View”条目&#xff0c;选中“Add Member Variable”菜单命令&#xff0c;如图4-6所示。


图4-6  添加变量

弹出“Add Member Variable”对话框&#xff0c;在Variable Type项中输入CString&#xff0c;在Variable Name项中输入m_str&#xff0c;单击“OK”按钮。如图4-7所示。

 
图4-7  “Add Member Variable”对话框

用同样的方法为CCDocument Doc类添加一个CString类型数据成员m_strText&#xff0c;该成员函数用于存储文档中的数据。
&#xff08;4&#xff09;添加代码
在CCDocumentDoc::Serialize()函数中输入如下代码&#xff1a;

void CCDocumentDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
ar<}
else
{
// TODO: add loading code here
ar>>m_strText;
}
}


在CCDocumentView::OnInitialUpdate()函数中输入以下代码&#xff1a;

void CCDocumentView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CCDocumentDoc* pDoc &#61; GetDocument();//获取文档指针
m_str&#61;pDoc->m_strText; //获取文档数据
UpdateData(FALSE); //初始化窗口数据
}


这段程序从文档对象获取数据&#xff0c;并用获取的数据对视图进行初始化。
在CCDocumentView::OnDraw()函数中输入如下代码&#xff1a;

void CCDocumentView::OnDraw(CDC* pDC)
{
CCDocumentDoc* pDoc &#61; GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

pDC->TextOut(100,100,m_str); //显示数组
}


在CCDocumentView::OnChar()函数中输入如下代码&#xff1a;

void CCDocumentView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CCDocumentDoc* pDoc&#61;GetDocument();   //获取当前文档对象的指针
ASSERT_VALID(pDoc);       //有效性检查
if (nChar&#61;&#61;&#39;\b&#39;)        //判断是否输入退格键
m_str.Delete(m_str.GetLength()-1,1);  //去掉字符串最后一个字符
else
m_str&#43;&#61;nChar;       //将键盘输入字符加入字符串中
Invalidate(); 
pDoc->m_strText&#61;m_str;      //将字符串传递给文档变量
pDoc->SetModifiedFlag(TRUE);     //设置最近修改的标志
CView::OnChar(nChar, nRepCnt, nFlags);
}


这段程序实现了将键盘字符串输入存储到视图数据m_str&#xff0c;并通过视图数据将字符串传递到文档数据m_strText中。
语句“pDoc”→“SetModifiedFlag(TRUE);”在文档数据修改后设置最近的修改标志&#xff0c;在用户关闭当前文档时&#xff0c;会提示用户进行保存。
&#xff08;5&#xff09;编译并运行程序
程序运行的结果&#xff0c;如图4-8所示。在这里我们键入的是“欢迎来到Visual C&#43;&#43; 6.0的世界&#xff01;”。

 
图4-8  程序运行结果

单击“文件”→“保存”或者直接按“保存”图标&#xff0c;都会弹出一个保存文件的对话框。这样我们就实现了对文档的存取。


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • 常用工具(一)
    1.时间戳在线转换工具(1)链接https:tool.lutimestamp(2)说明可以通过此工具:将时间戳转为具体时间点,也可以将具体时间点转为时间戳(3)效果2.JSON在线 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有