收藏 分享(赏)

文档与视图.doc

上传人:kpmy5893 文档编号:7747848 上传时间:2019-05-25 格式:DOC 页数:8 大小:68.50KB
下载 相关 举报
文档与视图.doc_第1页
第1页 / 共8页
文档与视图.doc_第2页
第2页 / 共8页
文档与视图.doc_第3页
第3页 / 共8页
文档与视图.doc_第4页
第4页 / 共8页
文档与视图.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、第八章 文档和视图学前提示文档和视图结构是 MFC 的一大特色,将数据的管理和显示隔离,文档对象是用来保护数据的,而视图对象则是用来显示数据的,并且允许对数据进行编辑。知识要点文档和视图之间的相互作用函数简单文档视图应用程序文档的读写一档多视8.1 文档和视图之间相互作用的函数文档对象是用来保存数据的,视图对象是用来显示数据的,并且允许对数据进行编辑。在文档,视图和应用程序框架之间包含了一系列非常复杂的相互作用过程,为了了解这一过程,这里首先学习有关文档类和视图类的几个非常重要的成员函数,其中有的为虚函数,用户经常需要在派生类中对它们进行重载,而有的不是虚函数,经常需要在派生类中对它们进行调用

2、。8.1.1 视图类的 GetDocument()函数视图对象只有一个与之相联系的文档对象,它所包含的 GetDocument()函数允许应用程序在视图中得到与之相联系的文档。GetDocument()返回的是指向文档的指针,利用这个指针就可以访问文档类或其派生类的成员函数及公有数据成员。当 Class Wizard 产生 CView 的派生类时,它同时也创建一个保护类型的 GetDocument() 函数,它返回的是指向文档的指针CMyDoc * CMyView:GetDocument()Return (CMyDoc*)m_pDocument;CDocument 类的 GetNextView

3、()成员函数用来在文档中得到指向视图列表的指针,文档对象通过这个指针遍历视图列表,对每个视图都调用一次该函数。这时常用到 CDocument类的成员函数 GetFirstViewPosition()和 GetNextView() ,其中 GetFirstViewPosition()返回文档视图列表中第一个视图的 POSITION 值,而 GetNextView()返回下一个视图。程序通常类似如下的形式;CMyDoc *pDoc; /CMyDoc 为 CDocument 的派生类CMyView *pMyView; /CMyView 为 CView 的派生类pMyDoc =pMyView-GetD

4、ocument();POSITION pos =pMyDoc-GetFirstViewPosition();while(pos !=NULL) pView =(CMyView *)pMyDoc-GetNextView();/对视图做相应的操作8.1.2 视图类的 OnUpdate()函数OnUpdate()函数是一个虚函数,当应用程序调用了 UpdateAllViews()函数时,应用程序框架就会相应地调用所有视图的 OnUpdate()函数,当然,也可以直接在派生类中调用它。通常视图派生类的 OnUpdate()函数访问文档,读取数据,对视图的数据成员或控制进行更新。另外,还可以利用 OnU

5、pdate()函数使视图的某部分无效,触发视图的 OnDraw()函数,利用文档数据来重新绘制窗口。 OnUpdate()函数类似于下面的形式void CMyView:OnUpdate(CView *pSender,LPARAM lHint,CObject *pHint)CMyDoc *pDoc = GetDocment();ASSERT_VALID(pDoc);/加入视图的初始代码其中的提示信息是 UpdateAllViews()函数直接传递过来的。默认的 OnUpdate()函数使整个窗口无效,我们可以重写该函数,利用提示信息来定义一个较小的无效区域当 CDocument de OnUpd

6、ateAllView()函数被调用时,如果 pSender 参数指向某个特定的视图,那么除了该指定的视图, ,文档所有其他视图的 OnUpdate()函数都会被调用8.1.3 视图类的 OnInitialUpdate()函数当应用程序被启动后,或当用户从 File 菜单中选择了 New 或 Open 命令时,CView 的OnInitialUpdate()函数会被调用,该函数是虚函数,CView 的 OnInitialUpdate()函数除了调用 OnUpdate()函数之外,不做其他任何事情用户也可以利用派生类的 OnInitialUpdate()函数对视图进行初始化。当应用程序启动后,应用

7、程序框架在调用了 OnCreate()函数后(如果对 OnCreate()函数后进行映射) ,会立即调用 OnInitialUpdate()函数。OnCreate ()函数只能被调用一次,而OnInitialUpdate()函数则可以被调用多次。8.1.4 文档类的 UpdateAllViews()函数如果由于某种原因,文档数据发生了改变,那么所有的视图都必须被通知到,以便它们能够对显示的数据进行相应的更新。这时就要用到 CDocument 类的 UpdateAllViews()函数。如果在文档派生类的成员函数中调用 UpdateAllViews()函数,那么它的第一个参数 pSender 应

8、为 NULL。如果是在视图派生类的成员函数中被调用,应该以如下方式将 pSender 参数置为当前视图GetDocument()-UpdateAllsView(this);其中。非空参数使得应用程序框架不再通知当前视图,因为读者假定当前视图已经自己进行了更新。该函数的原型如下void UpdateAllViews(CView *pSender,LPARAM lHint,CObject *pHint=NULL);其中 lHint 和 pHint 为提示参数,可以利用它们给视图提供一些特殊的与应用程序有关的信息,以便视图能决定哪些部分应该更新,这是对该函数的更高级的用法提示 应用程序框架为 CDo

9、cument 类定义了 DeleteContent()虚函数,当文档被关闭时,应用程序框架会自动调用该函数。用户如果需要对文档进行清理操作,就可以重写该函数,8.3 文档的读写用户处理的数据往往需要存盘永久备份。将文档类中的数据成员变量的值保存在磁盘文件中,或者将存储在文档文件中的数据读取到相应的成员变量中。这个读写过程称为文档序列化(Serialize)8.3.1 MFC 文档读写机制使用 MFC 文档应用程序结构可以很简单地进行文档读写操作,下面首先介绍对文档进行不同操作后,MFC 程序的具体运行过程(1 ) 创建空文档对于文档应用程序来说,在运行到应用程序类的 InitInstance(

10、)函数时,它会在调用了 AddDocTemplate()函数之后,通过 CWinApp:ProcessShellCommand()间接调用 CWinApp 的另一个非常有用的成员函数 OnFileNew,并以此完成下列工作(1 ) 构造文档对象,但并不从磁盘中读数据(2 ) 构造主框架窗口类 CMainFrame 的对象,并创建该主框架窗口,但不显示(3 ) 构造视图对象,并创建视图窗口,也不显示(4 ) 通过内部机制,使文档,主框架和视图“对象”之间“真正”建立联系。注意与 AddDocTemplate()函数的区别, AddDocTemplate()函数建立的是“类”之间的联系。(5 )

11、调用文档对象的 CDocument:OnNewDocument()函数,该函数将首先调用 CDocument:DeleteContents ()虚函数清除文档对象的内容,然后调用 SetModifiedFlag(FALSE)将文档修改标志清除。OnNewDocument() OnOpenDocument()菜单命令 File New菜单命令 File OpenSetModifiedFlag(FALSE)GetFile() 构造 CArchive 对象DeleteContents()DeleteContents()Serialize()SetModifiedFlag(FALSE)文档对象可用建立

12、与打开文档(6 ) 调用视图对象的 CView:OnInitialUpdate()虚函数对视图进行初始化操作(7 ) 调用框架对象的 CFramWnd:ActiveFram ()虚函数,以便显示出带有菜单,工具栏,状态栏以及视图窗口的主框架窗口。说明在当文档应用程序中,文档,主框架以及视图对象仅被创建一次,并且这些对象在整个运行过程中都有效。CWinApp:OnFileNew()函数被 InitInstance()函数所调用,但当用户选择“文件”菜单的“新建”命令时。CWinApp:OnFileNew()也会被调用,与InitInstance()不同的是。这种情况下不存在创建文档,主框架以及视

13、图对象,但上述过程的最后 3 个步骤仍然会被执行(2 ) 打开文档当 MFC AppWizard 创建文档应用程序时,它会自动将“文件“命令(ID 号为 ID_FILE_OPEN)映射到 CWinApp 的 OnFileOpen()成员函数。这一结果可以从应用类(。Cpp)的消息入口处得到验证OnFileOpen()函数还会进一步完成下列工作、(1 ) 弹出通用的“打开“文件对话框,供用户选择一个文档(2 ) 文档指定后,调用文档对象的 CDocument:OnOPenDocument()虚函数。该虚函数将首先调用 GetFile()获得给定文件的 CFile 指针,在调用DeleteCont

14、ents()清除文档对象的内容,然后用 CFile 指针创建一个CArchive 对对象交给 Serialize 函数完成读文件重建文档对象的工作,最后在调用 SetModifiedFlag(FALSE)将文档修改标志清除(3 ) 调用视图对象的 CView:OnInitialUpdate()虚函数除了使用“文件“菜单中”打开“命令外,用户也可以选择最近使用过的文件列表来打开相应的文档。在应用程序的运行过程中,系统会记录 4 个(默认)最近使用过的文件,并将文件名保存在 Windows 的注册表中。当每次启动应用程序时,应用程序都会把最近使用过的文件名称显示在”文件“菜单中。(3)保存文档当

15、MFC AppWizard 创建应用程序时,它会自动将“文件(file) “菜单中”保存“命令与文档类 CDocument 的 OnFileSave 函数还会进一步完成下列工作(1 ) 弹出通用的“保存“文件对话框,让用户提供一个文件名(2 ) 调用文档对象的 CDocument:OnsaveDocument()虚函数,该函数将首先询问文件的名字,调用 GetFile()获得给定文件的 CFile 指针,然后用 CFile 指针创建一个 CArchive 对象交给 Serialize 函数完成写文件的工作,最后再调用 SetModifiedFlag(FALSE)将文档修改标志清除。OnSave

16、Document()保存文档保存文档说明只有在保存文档之前还没有存过盘(亦即没有文件名)或读取的文档是“只读“的OnFileSave 函数才会弹出通用的“保存“文件对话框。否则,只执行第二步在“文件”菜单中还有一个“另存为”命令,它是与文档类 CDocument 的 OnFileSaveAs()函数相关联。不管文档有没有保存过,OnFileSaveAs()都会执行上述两个步骤上述将文档存盘的必要操作都是由系统自动完成的。菜单命令 File Sava 菜单命令 File SavaAsGetFile()构造 CArchive 对象Serialize()SetModifiedFlag(FALSE)文

17、件保存命令完成(4 )关闭文档当用户试图关闭文档(或 退出应用程序)时,应用程序会根据用户对文档的修改与否来进一步完成下列任务(1)若文档内容已被修改,则弹出一个消息对话框,询问用户是否需要将文档保存,若用户选择“是” ,则应用程序执行 OnFileSave()过程(2 )调用 CDocument:OnCloseDocument()虚函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类 CDocument 的 DeleteContents()清除文档数据说明MFC 应用程序通过 CDocument 的 protected 类型成员变量 m_bModified 的逻辑值;来判断程序员是

18、否对文档进行了修改,若 m_bModified 为“ 真” ,则表示文档被修改。对于程序员来说,可以通过 CDocument 的 SetModifiedFlag()成员函数或通过 IsModified()成员函数来访问 Modifie 的逻辑值,当文件创建,从磁盘中读出以及存盘时,文档的这个标记就被置为 FALSE(假) ,而当文档数据被修改时,程序员必须用 SetModifiedFlag()函数将该标记置为 TRUE。这样,当用户关闭文档时,应用程序才会显示询问消息对话框。由于多文档应用程序序列化过程基本上和单文档相似,因此这里无需重复(5 )文档读写操作从上述的单文档序列化过程可以看出,在

19、打开文档和保存文档时,系统会都会主动调用 Seriallize 函数,事实上,MFC AppWizard 在创建文档应用程序时已在文档类中重载了Serialize 函数,通过在该函数中添加代码可以达到实现数据序列化的目的。 如在 Ex_XXX 单文档应用程序的文档类中有这样的默认代码void CE_XXXDoc:Serialize(CArchive virtual BOOL CreateStatic(CWnd* pParentWnd,int nRows,int nCols,DWORD dwStyle = WS_CHILD | WS_VISIBLE,UINT nID = AFX_IDW_PANE

20、_FIRST );其中参数:pParentWnd 表示切分窗口的父框架窗口nMaxRows 表示窗口动态切分的最大行数(不能超过 2)nMaxCols 表示窗口动态切分的最大列数(不能超过 2)nRows 表示窗口静态切分的行数(不能超过 16)nCols 表示静态切分的列数(不能超过 16)sizeMin 表示切分时允许的窗口最小尺寸 .CSplitterWnd 列成员函数 CreateView 用为来静态窗口指定一个视图类,并创建窗口,其函数原型如下virtual BOOL CreateView(int row,int col,CRuntimeClass* pViewClass,SIZE sizeInit,CCreateContext* pContext );其中,row,col 用来指定具体的静态窗口,pViewClass 用来指定与静态窗口相联的视图类,sizeInit 表示视图窗口初始大小窗口分隔的支持类 CSplitterWnd CSplitterWnd 类主要为窗口分割提供了封装,窗口被分为各个窗口,由该类的对象负责管理。对 Windows 而言,静态分割窗口,在窗口创建时,窗口就已经创建好了,且窗格的数量和顺序不会改变,用用可以拖动分割条来调整窗格的大小窗口分割中的各个窗口视图都对应着同一文档对象

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报