收藏 分享(赏)

《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt

上传人:gnk289057 文档编号:4497228 上传时间:2018-12-31 格式:PPT 页数:80 大小:364KB
下载 相关 举报
《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt_第1页
第1页 / 共80页
《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt_第2页
第2页 / 共80页
《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt_第3页
第3页 / 共80页
《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt_第4页
第4页 / 共80页
《Visual C++程序设计教程》第七章框架窗口、文档和视图.ppt_第5页
第5页 / 共80页
点击查看更多>>
资源描述

1、第7章 框架窗口、文档和视图,7.1 应用程序组成结构,1单文档应用程序(Single Document Interface,SDI)在单文档界面程序中,用户在同一时刻只能操作一个文档,如记事本程序。在这些应用程序中,打开文档时会自动关闭当前打开的活动文档,若文档修改后尚未保存,会提示是否保存所做的修改。因为一次只开一个窗口,因此不像WORD那样需要一个窗口菜单。单文档应用程序一般都提供一个“文件”菜单,在该菜单下有一组命令,用于新建文档、打开已有文档、保存或另存为等。这类程序相对比较简单,常见的应用程序有终端仿真程序和一些工具程序。,2多文档应用程序(Multiple Document In

2、terface,MDI)在多文档界面应用程序中,允许同时操作多个文档,如Microsoft Word。可以打开多个文件(同时也就为每个文件打开一个窗口),可以通过切换活动窗口激活相应的文档进行编辑。多文档应用程序也提供一个“文件”菜单,用于新建、打开、保存文档。与单文档应用程序不同的是,它往往还提供一个“关闭”菜单项,用于关闭当前打开的文档。多文档应用程序还提供一个“窗口”菜单,管理所有打开的子窗口,包括对子窗口的新建、关闭、层叠、平铺等。关闭一个窗口时,窗口内的文档也被自动关闭。,3基于对话框的应用程序(Dialog based Application)基于对话框的应用程序非常简单,由应用程

3、序类、对话框类(可以作为其它控件的容器)构成。它的生命周期可概括为:通过应用程序类的InitInstance()函数,构造一个模式对话框对象;调用DoModal函数,让基于对话框的应用程序像对待普通对话框一样接收和分配消息;用户退出对话框后,程序也就随之结束。常见的基于对话框的应用程序有计算器等(以对话框为容器布局的程序)。,7.1.1 CMainFrame类和窗口,MFC应用程序主要由3部分组成:窗口、文档和视图。其中窗口是整个应用程序的载体,也是应用程序不可缺少的部分。 窗口也叫框架窗口,它可以分为两类:一类是主框架窗口(也叫主窗口),另一类是子框架窗口(也叫子窗口)。在MFC应用程序中,

4、框架(Framework)是应用程序所应具备的软件模块按一定的结构组成的集合。框架窗口可以理解为框架的可视化显示形式。,主框架窗口是应用程序放置在桌面(DeskTop)上的那个窗口,每个应用程序只能有一个主窗口,主窗口的标题栏上通常显示应用程序的名称。子框架窗口是应用程序主框架窗口内的子窗口,它占据了主框架窗口客户区的部分或全部。视图是子框架窗口内的子窗口,它占据了子框架窗口客户区的部分或全部。,图7-1标明了多文档应用程序中主框架窗口、子框架窗口和视图之间的关系。由于单文档应用程序没有子框架窗口,所以可以认为视图充满了整个主框架窗口。,使用MFC AppWizard创建单文档应用程序后,包含

5、主框架窗口类的文件分别为MainFrm.h和MainFrm.cpp。主框架窗口类是由CFrameWnd派生而来的,类名为CMainFrame。而对于多文档应用程序,主框架窗口由CMDIFrameWnd派生。,CMainFrame类有4个重要的函数:AssertValid、Dump、OnCreate和PreCreateWindow。这4个函数都是由应用程序向导自动声明和定义的,无须人为干预,不过了解它们的作用还是非常有必要的,在需要的情况下,用户还可以修改它们以达到预定效果。它们各自的功能如下: (1)AssertValid 函数用来诊断CMainFrame对象的有效性。 (2)Dump 函数用

6、来输出CMainFrame对象的状态信息。 (3)OnCreate 函数用来创建工具栏m_wndToolBar和状态栏m_wndStatusBar,而在视图窗口中是由基类CFrameWnd的成员函数OnCreate通过调用OnCreateClient函数创建的。 (4)PreCreateWindow 函数是一个虚函数。如果要创建一个非默认风格的窗口,可以重载这个函数,在函数中通过修改Createstruct结构参数来改变窗口类、窗口风格、窗口大小和位置等。,7.1.2 CDocument类和文档,CDocument类是CCmdTarget类的派生类,其派生关系如图74所示。CDocument类

7、为用户定义的文档类提供了基本的函数功能,它支持标准操作,如创建、装载、保存等。一个应用程序可以支持多种类型的文档,每种类型的文档都通过一个文档模板对象建立与各自视图的联系。,不论是SDI应用程序还是MDI应用程序,文档类都是从CDocument类派生出来的。在文档/视图结构中,文档类的主要任务通常是对数据进行管理和维护,数据将保存在文档类的成员变量中,视图通过对这些变量的访问来获取或返回数据,并能通过这种方式来更新并显示数据。,从CDocument类派生文档类的步骤如下: (1)为每一个文档类型从 CDocument类(当然也可以是其他 CDocument类的派生类)派生一个相应的文档类。 (

8、2)为文档类添加成员变量。这些成员变量用来保存文档的数据,其他对象(如与文档相关联的视图)直接或间接地访问这些成员变量以读取或更新文档的数据。 (3)重载Serialize成员函数,实现文档数据的序列化。,7.1.3 CView类和视图,CView类是CWnd类的派生类,其派生关系如图7-5所示。CView类是MFC中一个基本的类,也是其他MFC视图类和用户视图派生类的基类。,视图窗口用来显示文档中的数据,并根据视图对象提供的基本功能,指定用户使用什么方式查看文档数据,接受用户对数据的交互操作(包括选择和编辑),并将更改后的数据回传给文档。视图被附加到文档中并在文档和用户之间充当媒介,它可以在

9、屏幕上呈现文档的数据,并将用户输入解释为对文档的操作,还可以为打印和打印预览呈现图像。,在MFC类库的层次位置中,CView类是从CWnd类下派生的,掌握这个继承关系对用户来说是很有用的。例如,由于所有的从CView类派生的类也都是由CWnd类间接派生的,因此这些类具有CWnd的所有功能,如创建、移动、显示和隐藏窗口等,并且CView类可以接收任何Windows消息。 CView类只提供了基础框架,在MFC中派生了CView类的许多子类,为不同的应用提供了强大支持。这些视图类都不是直接派生于CView类,而是派生于CView的子类CCtrlView。CCtrlView类的派生类对应于Windo

10、ws通用控件,提供了与通用控件相对应的功能。下面简单地介绍一下视图类各派生类的情况。,1.CEditView 类 CEditView类主要用来支持类似编辑控件所要实现的功能,常见的文本操作基本上都是由该类支持实现的。 如果希望有一个具有简单编辑功能或附加功能的编辑窗口,就可以构造一个CEditView类型的对象。一个CEditView对象可以占有一个窗体的整个用户区。用户也可以通过从CEditView中派生自己的类来增加或改变基本功能,并可以声明能加入到文档模板中的类。,2.CTreeView 类 CTreeView类主要提供对一些树形控件所实现的功能的支持。它可以使数据的显示方式更富于变化。

11、 3.CListView 类 CListView类与CTreeView类类似,不同之处在于它提供了一种简捷地实现数据的不同显示方式的途径,为数据组织提供了多种手段。,4.CRichEditView 类 CRichEditView类主要提供对Rich文本操作的支持。Rich文本是既可以为文本,也可以为图形图像的一种特殊格式的文本。 5.CScrollView 类 CScrollView类的主要功能是提供视图的滚动显示。需要注意的是,以上介绍的几个类都是间接派生于CView类,而该类直接继承至CView类,这就决定了其动作的特殊性。,7.1.4 框架窗口、文档和视图的关系,文档/视图结构是MFC应

12、用程序中最基本的程序结构,它适用于大多数Windows应用程序。文档与视图完成了程序的大部分功能,它们是MFC应用程序的核心。 由MFC创建的应用程序的主线程序体现在应用类中,而应用类通过文档模板类将文档类、窗口类(SDI中的主窗口类或MDI中的子窗口类)、视图类联系在一起,组成一个有机整体,共同完成程序设计任务。单文档模板类CSingleDocTemplate和多文档模板类CMutiDocTemplate均由CDocTemplate类派生。单文档模板类支持单文档应用程序,多文档模板类支持多文档应用程序。,应用类CWinApp通过一个内部类CDocManager来管理文档模板类。CWinApp

13、类成员变量m_pDocManager是指向CDocManager类对象的指针。在CDocManager类中定义的指针链表,其每项都是一个指向文档模板对象的指针。实际上,应用类通过其链表成员管理应用程序的所有文档模板对象。,文档对象用来保存和管理数据,视图对象用于数据交互,应用程序框架用来管理不同文档显示界面。例如,程序设计要求用数据网格显示二维数据,同时还要求用图形显示二维数据,即这些数据来自同一文档,但以不同的视图方式显示。在这种情况下可以用框架中的文档模板把一个文档及两个视图组合在一起。,在程序运行时,CWinApp将创建一个CFrameWnd框架窗口实例,而框架窗口将创建文档模板,然后由

14、文档模板创建文档实例和视图实例,并将两者关联起来。一般来讲,用户只需对文档和视图进行操作,框架的各种行为已经被MFC安排好而不需要人为干预,这也是MFC设计文档/视图结构的本意,让用户将注意力放在完成任务上,而从界面编写中解放出来。文档/视图结构的数据交互如图7-6所示,两者的关系如图7-7所示。,图7-6 文档-视图结构的数据交互,图7-7 文档与视图的关系,框架窗口、文档和视图之间的关系可以表述为:文档和视图之间是一对多的关系,每个视图和框架窗口是一对一的关系。 框架窗口、文档和视图三者之间是相互关联、相互协调的,彼此都包含了指向对方的指针。它们之间的联系是通过文档模板的构造函数来实现的。

15、下面介绍在程序中如何得到各种对象的指针。,(1)全局函数AfxGetApp()可以得到CWinApp应用程序类指针,而AfxGetApp()-m_pMainWnd就是框架窗口CFrameWnd的指针。 (2)在框架窗口中,CFrameWnd:GetActiveDocument()得到当前活动文档指针。 (3)在框架窗口中,CFrameWnd:GetActiveView()得到当前活动视图指针。 (4)在视图中,CView:GetDocument()用于检索指向文档类的指针。 (5)在文档中,CDocument:GetFirstViewPosition()和CDocument:GetNextVi

16、ew()用来遍历所有和文档关联的视图。 (6)在文档中,CDocument:GetDocTemplate()用来得到文档模板指针。 (7)在多文档界面中,CMDIFrameWnd:MDIGetActive()得到当前活动的MDI子窗口。,7.2 文档,文档(Document)是MFC应用程序中所处理数据的集合,包括文本、图形、图像和表格等类型。一个文档对应于用户当前打开的一个文件。文档的主要作用是把数据处理从用户界面的管理中分离出来,集中处理数据,同时提供与视图交互的接口。,7.2.1 数据成员,数据成员包括成员变量和成员函数。CDocument类为用户定义的文档类提供了基本的函数功能。 CD

17、ocument支持标准操作,如创建、装载、保存等。框架用CDocument定义的界面来操作文档。CDocument类的主要成员变量如下:,CString m_strTitle:用于标记文档的标题。 CString m_strPathName:用于标记文档的路径。 CDocTemplate *m_pDocTemplate:指向文档模板的指针。 CPtrList m_viewList:视图列表。 BOOL m_bModified:指明打开文档后是否进行了修改。 BOOL m_bAutoDelete:在没有可用视图时是否删除自动文档。 BOOL m_bEmbedded:是否可通过OLE创建文档。,7

18、.2.2 成员函数,1.AddView函数函数原型如下:void AddView(CView *pView); 说明:为当前的文档添加一个视图。其中,参数pView 是指向新添加的视图的指针。 2.CanCloseFrame函数 函数原型如下:virtual BOOL CanCloseFrame(CFrameWnd *pFrame); 说明:应用程序调用该函数判断是否可以关闭pFrame指向的窗口。如果能关闭,则返回非零值,否则,返回FALSE。在默认情况下,该函数先测试这个窗口是否是文档的唯一窗口。如果是,则提示用户存盘。,3.DeleteContents函数 函数原型如下:virtual

19、void DeleteContents(); 说明:框架窗口调用该函数在不删除CDocument对象的前提下删除文档中的数据。当文档被重复使用时,调用该函数确保文档为空。 4.GetDocTemplate函数 函数原型如下:CDocTemplate *GetDocTemplate() const; 说明:调用该项函数得到一个指向当前文档使用的文档模板的指针。当文档不是由文档模板来管理时,返回NULL。,5.GetFile函数 函数原型如下: virtual CFile*GetFile(LPCTSTR lpszFIleName,UINT nOpenFlags,CFileException*pEr

20、ror); 说明:得到一个CFile对象的指针。其中,lpszFileName 为指定文件的路径的字符串,nOpenFlags为打开文件时指定文件的共享和存取方式,pError为指向错误代码的指针。 6.GetFirstViewPosition函数 函数原型如下: virtual POSITION GetFirstViewPosition() const; 说明:利用该函数可得到与文档相关的第一个视图的位置,返回值可以供GetNextView()函数使用。,7.GetNextView函数 函数原型如下: virtual CView *GetNextView(POSITION 说明:返回当前文档

21、存盘文件的完整路径。,9.GetTitle函数 函数原型如下: const CString 说明:检测文档是否被修改过。如果文档被修改过,返回TRUE。,11.OnChangedViewList函数 函数原型如下: virtual void OnChangedViewList(); 说明:在文档的视图增加或减少时调用。默认是当文档的最后一个视图被删除时自动删除文档。 12.OnCloseDocument函数 函数原型如下: virtual void OnCloseDocument(); 说明:关闭文档时被调用。默认先调用DeleteContents()函数删除文档数据,然后再关闭视图窗口。,1

22、3.OnNewDocument函数 函数原型如下: BOOL OnNewDocument(); 说明:在SDI应用程序中,当用户在“文件”菜单中单击“新建”菜单项时,自动调用框架窗口。OnNewDocument()消除旧文档内容,得到一个“空”的文档。而在MDI应用程序中,框架自动生成一个新的文档对象,如果要调用OnNewDocument()实现初始化,用户可以在此处插入一个新文档的初始化代码。,14.OnOpenDocument函数 函数原型如下: virtual BOOL OnOpenDocument(LPCTSTR lpszPathName); 说明:在打开文档的时候调用。其中,lpsz

23、PathName 为被打开文档的路径。 15.OnSaveOpenDocument函数 函数原型如下: virtual BOOL OnSaveDocument(LPCTSTR lpszPathName); 说明:当执行“保存”和“另存为”命令时被调用。默认时,调用CObject:Serialize函数将文档数据存入文件。如果操作成功,返回TRUE。,16.SaveModified函数 函数原型如下: virtual BOOL SaveModified(); 说明:当关闭一个被修改的文档时,调用该函数询问是否需要保存修改的文档。如果成功地关闭了文档,则返回TRUE。 17.SetModified

24、Flag函数 函数原型如下: void SetModifiedFlag(BOOL bModified=TRUE); 说明:设置文档的编辑标志。当用户保存文档后,文档的bModified自动被设置为FALSE。如果用户退出程序时,bModified的标志为TRUE,系统会自动提示用户是否保存文档。当用户在程序中某处修改了文档数据,在其后加上代码pDoc-SetModifiedFlag(TRUE)可以有效地保证数据的安全。,18.Serialize函数 函数原型如下: void Serialize(CArchive 说明:保证数据在文档类及其视图类中是一致的。视图类接受用户的输入,则会将界面数据存

25、储到文档数据中,而文档类中的数据发生了变化,也应该及时更新视图类数据,并刷新界面。,7.2.3 文档序列化,文档类中存储数据的方法有多种,例如,使用对象指针、动态对象数组、动态链式存储结构或哈希表来实现用户自定义数据的存储。文档类通过“序列化机制”来管理文档中数据的存取,序列化机制示意图如图7-8所示。,如图7-8 序列化机制,持久性(persistence)是指对象所具有的保存和加载其状态的能力,即对象能够在程序运行结束前将对象的当前状态写入永久性存储体中,以后在程序再运行时通过数据的读取而恢复对象的状态。这种对象的保存和恢复的过程称为序列化(serialize)。 为了深入理解序列化操作,

26、有必要了解对文档不同操作后的具体程序运行过程。,1.创建空文档 应用程序类的InitInstance()函数在调用了AddDocTemplate()函数之后,会通过CWinApp:ProcessShellCommand间接调用CWinApp的成员函数OnFileNew,并依次完成下列工作: (1)构造文档对象,从磁盘中读取数据。 (2)构造主框架类CMainFrame类的对象,并创建该主框架窗口,但不显示。 (3)构造视图对象,并创建视图窗口,同样也不显示。 (4)通过MFC内部机制,建立主框架窗口、文档和视图对象之间的联系。 (5)调用CDocument:OnNewDocument()虚函数

27、,并调用CDocument:DeleteContents()虚函数来清除文档对象的内容。 (6)调用CView:OnInitialUpdate()虚函数初始化视图类的数据成员。 (7)调用CFrameWnd:ActiveFrame()虚函数,显示带有菜单、工具栏、状态栏以及视图窗口的主框架窗口。,2.打开文档 在利用MFC应用程序向导创建应用程序时,MFC会自动将“文件”菜单中的“打开”命令映射到CWinApp类的OnFileOpen()成员函数。OnFileOpen()函数会完成下列操作: (1)弹出通用文件“打开”对话框,供用户选择一个文档。 (2)文档指定后,调用文档对象的CDoucme

28、nt:OnOpenDocument()虚函数。这个函数将打开文档,并调用DeleteContents()函数清除文档对象的内容,然后创建一个CArchive对象用于数据的读取,接着又自动调用Serialize()函数。 (3)调用视图对象的CView:OnInitialUpdate()虚函数初始化视图类的数据成员。,3.保存文档 在利用MFC应用程序向导创建应用程序时,它会自动将“文件”菜单中的“保存”命令与文档类的OnFileSave成员函数在内部关联。OnFileSave()函数会完成下列操作: (1)弹出通用文件“保存”对话框,让用户输入一个文件名。 (2)调用文档类对象的CDocume

29、nt:OnSaveDocument()虚函数,接着又自动调用Serialize()函数,将CArchive对象的内容保存在文档中。,4.关闭文档 当用户试图关闭文档(或退出应用程序)时,应用程序会根据用户对文档的修改与否来进一步完成下列任务。 (1)若文档内容已修改,则弹出一个“消息”对话框,询问用户是否保存修改后的文档。当用户选择“是”,则应用程序执行OnFileSave过程。 (2)调用CDocument:OnCloseDocument()虚函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类的DeleteContents清除文档数据。,用户经常需要自己定义类来实现序列化操作,以

30、完成某些特定的功能,MFC为满足用户的这个需要规定了自定义类实现序列化必须满足以下4个条件: (1)类必须是直接或间接地从CObject类派生。 (2)类必须定义一个不带参数的构造函数。当从磁盘载入文档时调用该构造函数来创建一个可序列化的对象,使用从文件中读出来的数据填充对象的成员变量。 (3)要使用MFC序列化宏。在类的头文件中使用DECLARE_SERIAL宏,在类的实现文件中使用IMPLEMENT_SERIAL宏。 (4)自定义类必须重载序列化成员函数Serialize()。由于不同类的数据结构各不相同,可序列化的类应该重载Serialize()函数,使其支持对特定数据的序列化。并且,任

31、何需要序列化的对象都应该在文档派生类中作为数据成员进行声明。,7.3 视图,视图(view)是文档在应用程序窗口中的一个映像。视图就像一个观景器,用户通过视图查看和修改文档,视图充当了文档与用户之间的媒介物。应用程序通过视图向用户显示文档中的数据,并把用户的输入解释为对文档的操作。一个视图总是与一个文档对象相关联,用户通过与文档相关联的视图与文档进行交互。当用户打开一个文档时,应用程序就会创建一个与之相关联的视图。,7.3.1 视图的特点,视图主要有以下几方面特点: (1)多个视图可以共享一个主窗口。 (2)CDocTemplate为视图、主窗口和文档之间建立相互联系。 (3)当用户打开或切分

32、窗口时,应用程序将构造一个视图,并将它连接到相应的文档。 (4)一个视图只能拥有一个文档,而一个文档可以拥有多个视图。,(5)视图接收由程序框架传给它的命令,如果视图不能处理该命令,就将其传递给相关联的文档处理。 (6)视图可处理多种类型的输入和命令,如键盘输入、鼠标输入、菜单命令、工具栏命令等。 (7)视图负责显示和修改文档数据。在应用程序中可以使用视图直接读取文档的数据,也可以在文档中提供由视图调用的函数来获取文档数据。,7.3.2 视图的成员函数,1.OnDraw函数 函数原型如下: void OnDraw(CDC*pDC); 其中,pDC为指向打印设备描述表的指针。 说明:当用户执行屏

33、幕显示、打印和打印预览时,框架将调用该函数在输出设备上显示文档数据,因此OnDraw函数是编程时需要覆盖的函数之一。,2.GetDocument函数 函数原型如下: CDocument *GetDocument() const; (CDocument 派生类) *GetDocument() const; 说明:获得与视图类相关连的文档对象指针。在视图类中可用GetDocument获取与之关联的文档对象的指针,取得对文档数据、对象、对象集合的访问。通过该函数还可以获得指向视图对象所属的文档的文档指针m_pDocument。,3.OnUpdate 函数 函数原型如下: virtual void O

34、nUpdate(CView *pSender,LPARAM lHint, CObject *pHint); 其中,参数“pSender”表示与被更改的文档类相关联的视图类的指针,当为NULL时,表示所有的视图都需要更新。 说明:OnUpdate函数是一个虚函数,它负责更新数据,对文档数据的正确显示起必要的支持作用。,4.OnInitialUpdate函数 函数原型如下: void OnInitialUpdate(); 说明:OnInitialUpdate函数用于初始化视图类的数据成员。 5.IsSelected函数 函数原型如下: virtual BOOL IsSelected(const C

35、Object*pDocItem)const; 说明:判断指定的文档项目是否被选中,如果没有选中,则返回零值,否则返回非零值。 该函数由框架调用,检查指定的文档项目是否被选中。pDocItem为指向要测试的文档项目的指针。,6.OnScroll 函数 函数原型如下: virtual BOOL CView:OnScroll(UINT nScrollCode,UINT nPos,BOOL bDoScroll=TRUE); 说明:框架调用这个函数以确定视图是否能够滚动。如果bDoScroll为TRUE,并且视图确实被滚动了,则返回非零值;否则返回零。如果bDoScroll为FALSE,则返回当bDoS

36、croll为TRUE时应当返回的值,即使没有做实际的滚动。,7.OnPrepareDC 函数 函数原型如下: virtual void OnPrepareDC(CDC *pDC, CPrintInfo *pInfo=NULL); 说明:在调用OnDraw()函数前允许由MFC调用该函数修改设备描述表。其中,参数pDC为指向设备环境的指针,用于画出文档的图像。pInfo 为指向CPrintInfo结构的指针,如果OnPrepareDC是为打印或打印预览调用的,则该结构描述了当前打印任务,m_nCurPage成员指定了要打印的页数。如果OnPrepareDC是为屏幕显示而调用的,则这个参数为NUL

37、L。,在下列情况下,应该重载OnPrepareDC: (1)要为指定的页面调整设备环境的属性。例如,如果想要设置设备环境的映射模式或者其他特征,则应在这个函数中完成这些操作。 (2)要实现打印时的分页。通常应当在打印开始时利用OnPreparePrinting成员函数来指定文档的长度。但是,如果并不知道文档的确切长度(例如,当打印数据库中未知数量的记录时),则应重载OnPrepareDC函数,以便在打印时检测是否到了文档的末尾。如果已经没有文档需要打印了,将CPrintInfo结构的m_bContinuePrinting成员设为FALSE。 (3)要按页发送打印机的转义序列码。要在OnPrep

38、areDC中发送转义序列码,则应调用pDC成员的Escape成员函数。,除了该函数,视图类还提供了其他4个关于打印的函数。 OnBeginPrinting函数:重载该函数可以创建打印文档所需要的资源。 OnEndPrinting函数:重载该函数可以释放在OnBeginPrinting函数中创建的资源。 OnPreParePrinting函数:重载该函数可以提供文档的最大打印页数。 OnPrint函数:重载该函数可以提供如打印页眉页脚等的附加打印服务。,7.3.3 视图的操作方法,CView 类及其派生视图类是用户的数据窗口,它控制着应用程序文档内容的显示以及用户和应用程序文档的交互。同时,CV

39、iew类的派生类分别支持各种不同的功能,可以根据需要选择适当的派生类。,对视图操作的一般步骤如下: (1)获得与其相关联的文档对象指针。在视图类中可用GetDocument获取与之关联的文档对象的指针,取得对文档数据、对象、对象集合的访问。例如,CDocument*pDoc=GetDocument()。 (2)在OnDraw函数中添加要重新绘制的模块。 在OnDraw函数中对需要重新绘制的功能模块再次操作,以避免在刷新视图时所绘内容丢失。例如,在该函数外绘制了一条直线pDC-LineTo(50,100),如果没有在这个函数内重新调用绘制直线的操作,在视图刷新后将看不到所绘直线。 (3)使用On

40、Update函数更新、同步数据。 OnUpdate函数负责更新数据,提供对文档正确显示的支持。数据一旦发生变化,利用这个函数就可以保持文档和视图中数据的一致性。,(4)通过界面与用户交互。 Windows标准消息是直接发送到视图对象的。在处理各种命令消息时,视图类的优先级也比较高,而且视图中显示文档数据。因此,使用视图对象对用户输入进行响应是理所当然的。 刷新视图时默认的函数调用过程是CDocument:UpdateAllViews()-CView:OnUpdate()-CWnd:Invalidate()-OnPaint()-OnDraw()。,7.4 基础实例 单文档应用程序,1.编程要求

41、编写一个简易的存储学生成绩信息的程序,具体功能要求为:首先通过对话框来输入一个学生记录,包括学生的姓名、学号和3门课程的成绩。然后,将记录内容保存到一个对象数组集合类对象中,最后通过文档序列化将记录保存到一个文件中。当添加记录或打开一个记录文件时,还会将数据显示在文档窗口(视图)中。,2.编程实现 1)添加用于输入学生成绩信息的对话框 2)添加一个CStudentScore类并使其可序列化 3)添加并处理菜单项 4)完善代码 5)编译运行并测试,结果如图7-10所示,7.5 提高实例 多文档应用程序,1.编程要求 编写一个一档多视的程序,在各自MDI文档窗口中包含同一个视图类的多个视图对象。这

42、个实例可以为同一个文档数据提供两种不同的显示和编辑方式,其效果如图7-11所示。,在左边的窗格中,用户可以输入起点坐标和终点坐标,相应的右边窗格中就会显示出以输入的起点和终点为坐标的一条直线;也可以在右边窗格中通过按鼠标左键拖动的方法改变左边窗格中的起点坐标和终点坐标,并在右边窗格中显示出相应的直线。,2.编程实现 (1)利用MFC AppWizard创建一个多文档应用程序DrawLineMDIApp。在“MFC应用程序向导-步骤6共6步”对话框中为CDrawLineMDIAppView类选择基类“CFormView”,如图7-12所示,其他步骤使用默认值即可。,(2)按图7-12的布局添加所

43、需控件,并对其进行相应的设置。该应用程序所需控件有3个组框,4个静态控件和4个编辑框。在工作区的ResourceView页面中双击Dialog下的“IDD_DRAWLINEMDIAPP_FORM”,添加控件。 最后,为编辑框控件添加成员变量。,(3)添加CDrawLineMDIAppDoc和CDrawLineMDIAppView类代码。 首先,在CDrawLineMDIAppDoc类中添加两个公有型的CPoint数据成员m_startPoint和m_endPoint,分别表示直线的开始坐标和终止坐标。 然后在CDrawLineMDIAppDoc类的构造函数内添加下列代码以初始化坐标。 CDra

44、wLineMDIAppDoc:CDrawLineMDIAppDoc() m_startPoint.x=m_startPoint.y=0;m_endPoint.x=m_endPoint.y=0; ,切换到MFC ClassWizard的Message Maps标签页,在CDrawLineMDIAppView类中为4个编辑框添加EN_CHANGE消息映射,将它们的映射函数名都设为OnChangeEdit,并添加如下代码以接收编辑框控件的值。,void CDrawLineMDIAppView:OnChangeEdit() /从编辑框中获取数据 UpdateData(); CDrawLineMDIAp

45、pDoc*pDoc=(CDrawLineMDIAppDoc*)GetDocument(); /直线的起始坐标 pDoc-m_startPoint.x=m_ptStartX; pDoc-m_startPoint.y=m_ptStartY; /直线的终止坐标 pDoc-m_endPoint.x=m_ptEndX; pDoc-m_endPoint.y=m_ptEndY; /刷新视图,并传递直线的起始坐标值 pDoc-UpdateAllViews(NULL,2,(CObject*) ,(4)添加CDrawView类,为框架增加窗口切分功能。 首先,利用MFC ClassWizard添加一个新的CVie

46、w类的派生类CDrawView。 然后利用MFC ClassWizard为CChildFrame类添加函数的重载,并添加下列代码。,在ChildFrm.cpp文件添加头文件引用:#include “DrawLineMDIAppView.h“#include “DrawView.h“ 在DrawView.cpp文件中添加头文件引用#include “DrawLineMDIAppDoc.h“ 打开ChildFrm.h文件,为CChildFrame类添加用于切分窗口的CSplitterWnd对象。,(5)为CDrawView类添加功能代码。 首先,为CDrawView类添加两个公有型的CPoint数

47、据成员m_startPoint和m_endPoint,用于记录直线的起始坐标和终止坐标。 然后,在CDrawView:OnDraw函数中添加下列代码: void CDrawView:OnDraw(CDC*pDC) CDocument*pDoc=GetDocument();/画直线pDC-MoveTo(m_startPoint);pDC-LineTo(m_endPoint); ,利用MFC ClassWizard为CDrawView类添加OnInitialUpdate的消息函数,并添加如下代码,用来初始化成员变量m_startPoint和m_endPoint。 void CDrawView:On

48、InitialUpdate() CView:OnInitialUpdate(); /通过文档类的成员变量m_pDocument获得与其相关联的文档指针 CDrawLineMDIAppDoc*pDoc=(CDrawLineMDIAppDoc*)m_pDocument; m_startPoint=pDoc-m_startPoint; m_endPoint=pDoc-m_endPoint; ,(6)利用MFC ClassWizard为CDrawView类添加OnUpdate的消息函数,并添加如下代码: void CDrawView:OnUpdate(CView*pSender, LPARAM lHint, CObject*pHint) /lHint等于2或4是一标志性变量,区别于1和3 /在刷新视图时,有选择地刷新 if(lHint=2) CPoint*pPoint=(CPoint*)pHint; m_startPoint=*pPoint; Invalidate(); ,if(lHint=4)CPoint*pPoint=(CPoint*)pHint;m_endPoint=*pPoint;Invalidate(); ,(7)编译运行程序,并测试功能的正确性,运行结果如图7-11所示。,本章结束,

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

当前位置:首页 > 实用文档 > 简明教程

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


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

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

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