




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第八章 文档和视图学前提示文档和视图结构是 MFC 的一大特色,将数据的管理和显示隔离,文档对象是用来保护数据的,而视图对象则是用来显示数据的,并且允许对数据进行编辑。知识要点文档和视图之间的相互作用函数简单文档视图应用程序文档的读写一档多视8.1 文档和视图之间相互作用的函数文档对象是用来保存数据的,视图对象是用来显示数据的,并且允许对数据进行编辑。在文档,视图和应用程序框架之间包含了一系列非常复杂的相互作用过程,为了了解这一过程,这里首先学习有关文档类和视图类的几个非常重要的成员函数,其中有的为虚函数,用户经常需要在派生类中对它们进行重载,而有的不是虚函数,经常需要在派生类中对它们进行调用。8.1.1 视图类的 GetDocument()函数视图对象只有一个与之相联系的文档对象,它所包含的 GetDocument()函数允许应用程序在视图中得到与之相联系的文档。GetDocument()返回的是指向文档的指针,利用这个指针就可以访问文档类或其派生类的成员函数及公有数据成员。 当 Class Wizard产生 CView 的派生类时,它同时也创建一个保护类型的 GetDocument() 函数,它返回的是指向文档的指针CMyDoc * CMyView:GetDocument() Return (CMyDoc*)m_pDocument; CDocument 类的GetNextView()成员函数用来在文档中得到指向视图列表的指针,文档对象通过这个指针遍历视图列表,对每个视图都调用一次该函数。这时常用到 CDocument类的成员函数 GetFirstViewPosition()和 GetNextView(),其中 GetFirstViewPosition()返回文档视图列表中第一个视图的POSITION值,而GetNextView()返回下一个视图。程序通常类似如下的形式;CMyDoc *pDoc; /CMyDoc 为 CDocument 的派生类CMyView *pMyView; /CMyView 为 CView 的派生类pMyDoc =pMyView-GetDocument();POSITION pos =pMyDoc-GetFirstViewPosition();while(pos !=NULL) pView =(CMyView *)pMyDoc-GetNextView();/对视图做相应的操作8.1.2 视图类的 OnUpdate()函数 OnUpdate()函数是一个虚函数,当应用程序调用了 UpdateAllViews()函数时,应用程序框架就会相应地调用所有视图的 OnUpdate()函数,当然,也可以直接在派生类中调用它。通常视图派生类的 OnUpdate()函数访问文档,读取数据,对视图的数据成员或控制进行更新。另外,还可以利用 OnUpdate()函数使视图的某部分无效,触发视图的 OnDraw()函数,利用文档数据来重新绘制窗口。 OnUpdate()函数类似于下面的形式 void CMyView:OnUpdate(CView *pSender,LPARAM lHint,CObject *pHint)CMyDoc *pDoc = GetDocment();ASSERT_VALID(pDoc);/加入视图的初始代码其中的提示信息是 UpdateAllViews()函数直接传递过来的。默认的OnUpdate()函数使整个窗口无效,我们可以重写该函数,利用提示信息来定义一个较小的无效区域当CDocument de OnUpdateAllView()函数被调用时,如果pSender参数指向某个特定的视图,那么除了该指定的视图,文档所有其他视图的OnUpdate()函数都会被调用 8.1.3 视图类的 OnInitialUpdate()函数当应用程序被启动后,或当用户从File菜单中选择了New或 Open命令时,CView的OnInitialUpdate()函数会被调用,该函数是虚函数,CView的OnInitialUpdate()函数除了调用 OnUpdate()函数之外,不做其他任何事情用户也可以利用派生类的OnInitialUpdate()函数对视图进行初始化。当应用程序启动后,应用程序框架在调用了 OnCreate()函数后(如果对OnCreate()函数后进行映射),会立即调用OnInitialUpdate()函数。OnCreate()函数只能被调用一次,而OnInitialUpdate()函数则可以被调用多次。8.1.4 文档类的 UpdateAllViews()函数 如果由于某种原因,文档数据发生了改变,那么所有的视图都必须被通知到,以便它们能够对显示的数据进行相应的更新。这时就要用到 CDocument类的UpdateAllViews()函数。如果在文档派生类的成员函数中调用UpdateAllViews()函数,那么它的第一个参数 pSender 应为NULL。如果是在视图派生类的成员函数中被调用,应该以如下方式将 pSender参数置为当前视图GetDocument()-UpdateAllsView(this);其中。非空参数使得应用程序框架不再通知当前视图,因为读者假定当前视图已经自己进行了更新。该函数的原型如下void UpdateAllViews(CView *pSender,LPARAM lHint,CObject *pHint=NULL);其中 lHint和 pHint为提示参数,可以利用它们给视图提供一些特殊的与应用程序有关的信息,以便视图能决定哪些部分应该更新,这是对该函数的更高级的用法提示 应用程序框架为 CDocument类定义了 DeleteContent()虚函数,当文档被关闭时,应用程序框架会自动调用该函数。用户如果需要对文档进行清理操作,就可以重写该函数, 8.3 文档的读写 用户处理的数据往往需要存盘永久备份。将文档类中的数据成员变量的值保存在磁盘文件中,或者将存储在文档文件中的数据读取到相应的成员变量中。这个读写过程称为文档序列化(Serialize)8.3.1 MFC 文档读写机制 使用MFC文档应用程序结构可以很简单地进行文档读写操作,下面首先介绍对文档进行不同操作后,MFC程序的具体运行过程(1) 创建空文档对于文档应用程序来说,在运行到应用程序类的 InitInstance()函数时,它会在调用了 AddDocTemplate()函数之后,通过CWinApp:ProcessShellCommand()间接调用 CWinApp的另一个非常有用的成员函数 OnFileNew,并以此完成下列工作(1) 构造文档对象,但并不从磁盘中读数据(2) 构造主框架窗口类CMainFrame的对象,并创建该主框架窗口,但不显示(3) 构造视图对象,并创建视图窗口,也不显示(4) 通过内部机制,使文档,主框架和视图“对象”之间“真正”建立联系。注意与 AddDocTemplate()函数的区别,AddDocTemplate()函数建立的是“类”之间的联系。(5) 调用文档对象的 CDocument:OnNewDocument()函数,该函数将首先调用CDocument:DeleteContents()虚函数清除文档对象的内容,然后调用SetModifiedFlag(FALSE)将文档修改标志清除。菜单命令 File New菜单命令 File OpenSetModifiedFlag(FALSE)GetFile() 构造CArchive 对象DeleteContents()DeleteContents()Serialize()SetModifiedFlag(FALSE)文档对象可用 OnNewDocument() OnOpenDocument() 建立与打开文档(6) 调用视图对象的CView:OnInitialUpdate()虚函数对视图进行初始化操作(7) 调用框架对象的 CFramWnd:ActiveFram()虚函数,以便显示出带有菜单,工具栏,状态栏以及视图窗口的主框架窗口。说明在当文档应用程序中,文档,主框架以及视图对象仅被创建一次,并且这些对象在整个运行过程中都有效。CWinApp:OnFileNew()函数被 InitInstance()函数所调用,但当用户选择“文件”菜单的“新建”命令时。CWinApp:OnFileNew()也会被调用,与InitInstance()不同的是。这种情况下不存在创建文档,主框架以及视图对象,但上述过程的最后3个步骤仍然会被执行(2) 打开文档 当MFC AppWizard创建文档应用程序时,它会自动将“文件“命令(ID号为 ID_FILE_OPEN)映射到CWinApp的OnFileOpen()成员函数。这一结果可以从应用类(。Cpp)的消息入口处得到验证OnFileOpen()函数还会进一步完成下列工作、(1) 弹出通用的“打开“文件对话框,供用户选择一个文档(2) 文档指定后,调用文档对象的CDocument:OnOPenDocument()虚函数。该虚函数将首先调用GetFile()获得给定文件的 CFile 指针,在调用DeleteContents()清除文档对象的内容,然后用CFile指针创建一个CArchive 对对象交给Serialize函数完成读文件重建文档对象的工作,最后在调用SetModifiedFlag(FALSE)将文档修改标志清除(3) 调用视图对象的CView:OnInitialUpdate()虚函数 除了使用“文件“菜单中”打开“命令外,用户也可以选择最近使用过的文件列表来打开相应的文档。在应用程序的运行过程中,系统会记录4个(默认)最近使用过的文件,并将文件名保存在Windows的注册表中。当每次启动应用程序时,应用程序都会把最近使用过的文件名称显示在”文件“菜单中。(3)保存文档当MFC AppWizard创建应用程序时,它会自动将“文件(file)“菜单中”保存“命令与文档类 CDocument 的OnFileSave函数还会进一步完成下列工作(1) 弹出通用的“保存“文件对话框,让用户提供一个文件名(2) 调用文档对象的 CDocument:OnsaveDocument()虚函数,该函数将首先询问文件的名字,调用GetFile()获得给定文件的CFile指针,然后用CFile 指针创建一个CArchive对象交给Serialize 函数完成写文件的工作,最后再调用SetModifiedFlag(FALSE)将文档修改标志清除。菜单命令 File Sava菜单命令 File SavaAsGetFile()构造CArchive对象Serialize()SetModifiedFlag(FALSE)文件保存命令完成 OnSaveDocument() ) 保存文档 保存文档说明只有在保存文档之前还没有存过盘(亦即没有文件名)或读取的文档是“只读“的OnFileSave函数才会弹出通用的“保存“文件对话框。否则,只执行第二步在“文件”菜单中还有一个“另存为”命令,它是与文档类CDocument 的 OnFileSaveAs()函数相关联。不管文档有没有保存过,OnFileSaveAs()都会执行上述两个步骤 上述将文档存盘的必要操作都是由系统自动完成的。(4)关闭文档当用户试图关闭文档(或 退出应用程序)时,应用程序会根据用户对文档的修改与否来进一步完成下列任务(1)若文档内容已被修改,则弹出一个消息对话框,询问用户是否需要将文档保存,若用户选择“是”,则应用程序执行 OnFileSave()过程(2)调用 CDocument:OnCloseDocument()虚函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类CDocument的DeleteContents()清除文档数据说明MFC应用程序通过 CDocument 的protected类型成员变量m_bModified的逻辑值;来判断程序员是否对文档进行了修改,若m_bModified 为“真”,则表示文档被修改。对于程序员来说,可以通过CDocument的SetModifiedFlag()成员函数或通过IsModified()成员函数来访问Modifie的逻辑值,当文件创建,从磁盘中读出以及存盘时,文档的这个标记就被置为FALSE(假),而当文档数据被修改时,程序员必须用 SetModifiedFlag()函数将该标记置为TRUE。这样,当用户关闭文档时,应用程序才会显示询问消息对话框。由于多文档应用程序序列化过程基本上和单文档相似,因此这里无需重复(5)文档读写操作从上述的单文档序列化过程可以看出,在打开文档和保存文档时,系统会都会主动调用 Seriallize函数,事实上,MFC AppWizard 在创建文档应用程序时已在文档类中重载了Serialize函数,通过在该函数中添加代码可以达到实现数据序列化的目的。 如在 Ex_XXX 单文档应用程序的文档类中有这样的默认代码void CE_XXXDoc:Serialize(CArchive &ar)if(ar.IsStoring() /当文档数据需要存盘时else /当文档数据需要读取时其中,Serialize函数的参数 ar是一个CArchive类引用变量。通过判断 ar.IsStoring的结果是“真”,还是“假”就可以决定文档写或读数据CArchive(归档)类提供对文件数据进行缓存,它同时还保存一个内部标记,用来标识文档是存入(写盘)还是载入(读盘)。每次只能有一个活动的存档与ar相连。通过 CArchive类就可以简化文件操作,它提供“”运算符,用于向文件写入简单的数据类型以及从文件中读取它们8.4 切分窗口 切分窗口是一种“特殊“的文档窗口,它可有有许多窗格,在窗格中又可包含若干个视图8.4.1 CSplitterWnd类操作在MFC中CSplitterWnd类封装了窗口切分过程中所需要的功能函数,其中成员函数Create和CreateStatic分别用来创建“动态切分”和静态“切分”的文档窗口,具体函数原型如下virtual BOOL Create( CWnd* pParentWnd, int nMaxRows, int nMaxCols, SIZE sizeMin, CCreateContext* pContext, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT, UINT nID = AFX_IDW_PANE_FIRST );virt
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 情感交互评估体系-洞察及研究
- 极端地幔部分熔融-洞察及研究
- 金融风险压力测试指标体系-洞察及研究
- 有机合成工艺改进指南
- Linux日常故障处理预案
- 北京市政劳务分包问题剖析与治理路径探索
- LTE系统同步算法与实现方法的深度剖析与创新研究
- 教育领域知识图谱构建方法-洞察及研究
- 物联网设备数据的有效管理-洞察及研究
- 沉淀物资源化利用研究-洞察及研究
- 读书分享会红色书籍《保卫延安》课件
- 华能集团薪酬管理制度
- T/CIE 147-2022空间行波管加速寿命试验评估技术规范
- 系统性淀粉样变性护理
- 化工过程安全管理导则 (一)
- 四川成都经济技术开发区(龙泉驿区)“蓉漂人才荟”招聘笔试题库2025
- 解除委托退费协议书
- 国家能源集团共享服务中心有限公司-企业报告(业主版)
- 国民经济行业分类代码(2024年版)
- 《缺血性卒中脑细胞保护临床实践中国专家共识(2025年版)》解读
- 《顺丰速运探索》课件
评论
0/150
提交评论