VisualC++程序设计与应用教程(下)课件_第1页
VisualC++程序设计与应用教程(下)课件_第2页
VisualC++程序设计与应用教程(下)课件_第3页
VisualC++程序设计与应用教程(下)课件_第4页
VisualC++程序设计与应用教程(下)课件_第5页
已阅读5页,还剩293页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Visual C+程序设计与应用主编 马石安 魏文平清华大学出版社1第1页,共298页。主要内容第1章 Visual C+开发环境第2章 MFC应用程序第3章 图形与文本第4章 菜单、工具栏与状态栏第5章 对话框第6章 Windows常用控件第7章 文档与视图第8章 打印编程第9章 动态链接库编程第10章 多线程编程第11章 数据库编程第12章 多媒体编程2第2页,共298页。第 5 章 对话框 5.1 对话框概述 5.2 模式对话框 5.3 非模式对话框 5.4 属性页对话框 5.5 通用对话框 5.6 应用实例Visual C+程序设计与应用教程3第3页,共298页。5.1 对话框概述5.

2、1.1 对话框的类型主要有以下两种:模式(Model)对话框无模式(Modeless)对话框 4第4页,共298页。5.1.2 对话框的CDialog类 CDialog类从CWnd类派生而来,所以它继承了CWnd类的成员函数,具有CWnd类的基本功能,可以编写代码移动、显示或隐藏对话框,并能根据对话框的特点增加新的成员函数,扩展它的功能。 5第5页,共298页。6第6页,共298页。7第7页,共298页。对话框主要由以下两部分组成:(1) 对话框模板:对话框模板定义了对话框的特性(比如大小、位置和风格)以及对话框中每个控件的类型和位置。(2) 对话框类:从CDialog类派生的对话框类提供编程

3、接口来管理对话框。5.1.3 对话框的组成8第8页,共298页。5.2 模态对话框对于模式对话框的编程可以按以下步骤进行。(1) 根据要求创建对话框模板。(2) 使用ClassWizard创建对话框类并进行各类事件函数的代码编写。(3) 对视图类进行编辑,以便对话框能够被激活。 9第9页,共298页。5.2.1 设计对话框模板资源 打开对话框编辑器:使用菜单【Insert|Resource】打开Insert Resource对话框,选中Dialog后单击New按钮。使用项目的ResourceView,找到Dialog资源,右击后选择Insert Dialog。对话框编辑器如下图所示。10第10

4、页,共298页。对话框模板控件布局工具栏控件工具栏11第11页,共298页。对话框模板Controls工具Dialog工具栏调整对话框显示时的大小和位置 拖放各种类型的控件到对话框中 调整控件的位置,测试对话框的外观和行为 12第12页,共298页。设计对话框模板资源有两个重要的内容:从Controls工具栏中选择控件(Control,功能各异的小小零组件)加到对话框中,并调整其位置和大小设置控件的Caption、ID以及其他属性 13第13页,共298页。1增加或删除控件增加控件:从控件工具栏中选中要增加的控件,再将此控件拖动至对话框模板中的确定位置上删除控件:先单击对话框中的控件,再按De

5、lete键 14第14页,共298页。2设置控件属性属性设置在与每个控件相对应的属性对话框中进行。打开控件属性对话框:在控件上右击鼠标,在弹出的快捷菜单中选择Properties 选择控件,选择View|Properties菜单项15第15页,共298页。控件属性对话框 16第16页,共298页。对话框的属性也是在对话框的属性对话框中设置。 在对话框任意空白处单击鼠标右键,在弹出的快捷菜单中选择Properties 。17第17页,共298页。3测试对话框的运行效果 测试对话框的方法有下面3种:选择菜单项Layout |Test。单击布局工具栏上的Test按钮。按快捷键Ctrl+T。18第18

6、页,共298页。【例5.1】创建一个单文档的应用程序MyDialog,向应用程序中添加如图所示的对话框模板资源,并设置控件的Caption、ID属性。 19第19页,共298页。5.2.2 设计对话框类主要包括下面几个方面:从MFC的CDialog中派生出一个类,用来负责对话框行为。利用ClassWizard把这个类和已编辑完成的对话框资源连接起来。 这意味着必须声明某些函数,用以处理相应的对话框消息,并将对话框中的控件对应到类的成员变量上,这也就是所谓的对话框数据交换(DDX,Dialog Data eXchange)。如果对这些变量内容有“确认规则”的话,ClassWizard也允许设定,

7、这就是所谓的对话框数据验证(DDV,Dialog Data Validation)。对话框的初始化。 20第20页,共298页。1.创建对话框类【例5.2】完善例5.1中的应用程序MyDialog,给对话框资源添加相应的对话框类。21第21页,共298页。2.创建对话框成员变量 ClassWizard类向导的Member Variables页面用来为对话框类添加和删除与对话框控件关联的成员变量。22第22页,共298页。【例5.3】继续完善例5.2中的应用程序,在对话框类中添加与控件相关联的成员变量。23第23页,共298页。3对话框的初始化使用以下3种方法:(1) 在构造函数中初始化 主要针

8、对对话框的数据成员。(2) WM_CREATE初始化(3) WM_INITDIALOG初始化24第24页,共298页。5.2.3 运行对话框模态对话框的运行分两个步骤:创建一个对话框对象调用CDialog:DoModal()函数打开对话框 DoModal()函数负责模态对话框的创建和撤消,可以根据其回值是IDOK还是IDCANCEL来判断用户关闭对话框时按的哪一个键。 25第25页,共298页。【例5.4】完善例5.3中的应用程序,通过【对话框|模态对话框】菜单项,打开上述标题为“输入边长”的对话框,并根据输入的边长画一个正方形。26第26页,共298页。5.2.4 对话框数据交换和校验机制

9、CDialog类通过调用其成员函数DoDataExchange()实现对话框数据交换和验证,在DoDataExchange()中使用了MFC提供的CDataExchange类,该类实现对话框类的成员变量与控件之间的数据交换DDX和数据验证DDV。 DDX将成员变量与对话框控件相连接,完成数据在成员变量和控件之间的交换。DDV用于数据的校验,它能自动校验输入的数据(如字符串的长度或数值的范围)是否符合设计要求。27第27页,共298页。 DoDataExchange()函数由框架调用。在应用程序MyDialog中,可以找到下列函数:void CSquare:DoDataExchange(CDat

10、aExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CSquare)DDX_Text(pDX, IDC_LENGTH, m_length);DDV_MinMaxInt(pDX, m_length, 10, 200);/AFX_DATA_MAPDDX函数调用语句,表明m_length是一个Value值类别的成员变量,用于交换IDC_LENGTH控件中内容 DDV函数调用语句,程序运行后,如果用户的输入数据超出10200的范围,DDV将显示提示信息对话框,提示用户有效的输入范围28第28页,共298页。 控件与成员变量之间的数据交换通过

11、调用UpdateData()函数进行。UpdateData()函数只有一个BOOL类型的参数当参数为TRUE时,MFC通过调用DoDataExchange()函数将数据从控件传递到关联的成员变量当参数为FALSE时,数据从成员变量传递到关联的控件。如下图所示。29第29页,共298页。30第30页,共298页。5.3 非模态对话框5.3.1 非模态对话框的特点与模态对话框比较:相同:创建对话框资源、添加对话框类、添加成员变量和消息处理函数的方法不同:创建和退出对话框的方式31第31页,共298页。1.Visible属性 模态对话框不需要设置该属性,而非模态对话框必须具有Visible风格,否则

12、对话框是不显示的。 另一种方法是调用CWnd:ShowWindow(SW_ SHOW)来显示对话框。32第32页,共298页。2.对话框窗口的创建方式 非模态对话框的创建是通过调用CWnd:Create()函数来实现的。 Create()函数与DoModal()函数不同之处是:Create()创建对话框后立即返回,而DoModal()函数在对话框关闭后才会返回。33第33页,共298页。3.对话框对象的创建方式 由于在Create()返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,所以不能以局部变量的形式创建非模态对话框的对象,只能用new操作符动态创建,并且在调用对话框

13、类的窗口类内声明一个指向对话框类的指针变量,通过该指针访问对话框对象。34第34页,共298页。4.窗口删除函数 非模态对话框必须调用CWnd:DestoryWindow()来关闭对话框。 模态对话框是调用CDialog:EndDialog()关闭对话框。由于默认的对话框函数OnOK()和OnCancel()都是调用EndDialog()关闭对话框的,该函数使对话框不可见但不删除对话框对象。所以非模态对话框类要定义自己的OnOK()和OnCancel()函数,调用DestoryWindow()来关闭对话框。35第35页,共298页。5.清理对话框对象的方式 与创建对象的方式new操作相对应,使

14、用delete操作删除一个非模态对话框对象。 当屏幕上一个窗口被关闭后,框架会自动调用CWnd:PostNcDestroy()函数,也可以编写程序代码,在这个函数中清理非模态对话框对象。36第36页,共298页。6. 必须有一个标志表明非模态对话框是否是打开的 因为在非模态对话框打开的情况下,用户有可能再次选择打开该对话框,这时不能再创建一个新的非模态对话框。 程序根据标志来判断是打开一个新的对话框还是激活一个已打开的对话框。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指针赋NULL值,以表明对话框对象已不存在了。37第37页,共298页。【例5.5】创建一个

15、单文档的MFC应用程序,以非模态对话框的形式实现应用程序MyDialog同样的功能。38第38页,共298页。5.3.2 窗口对象的自动清除(自学)39第39页,共298页。5.4 属性页对话框 属性页对话框实际上是一个包含了多个子对话框的对话框,这些子对话框通常被称为页(Page)。每次只有一个页是可见的,在对话框的顶端有一行标签,用户通过单击这些标签可以切换到不同的页。 为了支持属性页对话框,MFC提供了CPropertySheet类和CPropertyPage类。分别代表属性页对话框和对话框中的某一页。40第40页,共298页。【例5.6】创建一个单文档的MFC应用程序Li5_6,通过【

16、对话框|属性页对话框】菜单项,打开如图所示的对话框。当按确定按钮后,将在消息框中输出相关信息。41第41页,共298页。【例5.6】使用CpropertySheet派生类对象来创建与例5.5同样的属性页对话框。42第42页,共298页。5.5 通用对话框 43第43页,共298页。5.5.1 CFileDialog类 用CFileDialog类提供的通用文件对话框,实现Windows标准的【打开】和【另存为】功能。 44第44页,共298页。使用CFileDialog可按以下步骤进行。构造CFileDialog类的对象。该类的构造函数为:CFileDialog(BOOL bOpenFileDi

17、alog,值为TRUE,构造【打开】对话框;值为 FALSE,构造“另存为”对话框LPCTSTR lpszDefExt=NULL,默认的文件扩展名LPCTSTR lpszFileName=NULL,出现在文件名编辑框中的初始文件名DWORD dwFlags=OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter=NULL,CWnd *pParentWnd=NULL文件过滤器, 用于确定显示在文件列表中的文件类型)45第45页,共298页。 例如,以下字符串就是一个描述只在文件列表框中显示文本文件(*.txt)和Microsoft文件

18、(*.doc)的过滤器。CFileDialog dlg(TRUE,bmp,*.bmp, OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT,文本文件(*.txt)|*.txt|Word文件(*.doc)|*.doc|);第1个参数TRUE:【打开】对话框;第2个参数“bmp”:如果在文件名对话框中输入文件名时未指定扩展名,则会自动附加“.bmp”;第3个参数“*.bmp”:文件名对话框中的初始文件名是*.bmp;第4个参数代表dwFlags:不显示隐藏文件,且可以在列表框中进行多选;第5个参数是过滤器:在文件类型下拉列表框中显示了文本文件(*.txt)和Word文件(*

19、.doc)。 46第46页,共298页。(2) 调用成员函数DoModal( ),将对话框显示在屏幕上,并让用户从中选择文件。(3) 如果DoModal( )返回的是IDOK,那么调用下表中的成员函数获取文件信息。47第47页,共298页。【例5.7】创建一个单文档的MFC应用程序Li5_7,利用文件存取对话框取得一个文件的路径名。48第48页,共298页。5.5.2 CColorDialog类 CColorDialog类提供了可以选择颜色的对话框,使得用户可以从颜色列表中选择要用的颜色。对该类的使用可按下列步骤进行:(1) 在视图类相应位置构造CColorDialog对象。(2) 设置或修改

20、成员变量m_cc来初始化对话框。m_cc的结构类型为COLORREF。(3) 调用成员函数DoModal()来显示对话框并让用户从中选择颜色。49第49页,共298页。 (4) 如果DoModal()返回的是IDOK,那么用户所做的颜色选择将保存在m_cc中。通过使用该类的成员函数GetColor()即可得到选择颜色的RGB值。【例5.8】创建一个单文档的MFC应用程序Li5_8,利用颜色选择对话框选择颜色,并在视图区画一个该颜色的矩形。50第50页,共298页。5.5.3 CFontDialog类 CFontDialog类封装了标准的【字体】对话框,使得用户可以从系统安装的字体列表中选择要用

21、的字体。 CFontDialog类的使用步骤与CColorDialog的使用过程是一样的,只是m_cc的结构类型为LOGFONT。 在选择了字体后,可通过下表中的成员函数获取所选择的字体信息。51第51页,共298页。52第52页,共298页。【例5.9】创建一个单文档的MFC应用程序Li5_9,利用字体选择对话框选择字体的属性,并在视图区以该属性显示文本信息。53第53页,共298页。5.5.4 CPrintDialog类和CPageSetupDialog类 CPrintDialog类支持打印和打印设置对话框,通过这两个对话框用户可以进行与打印有关的设置。54第54页,共298页。5.5.5

22、 CFindReplaceDialog类 CFindReplaceDialog类用于实现查找和替换对话框。这两个对话框都是非模态对话框,用于在正文中查找和替换指定的字符串。 55第55页,共298页。5.6 应用实例 制作一个简单的计算器,实现加、减、乘、除、求倒数和平方根的混合运算,并能进行清屏及倒退操作。56第56页,共298页。第 7 章 文档与视图 7.1 文档/视图结构 7.2 简单的文档/视图结构应用程序 7.3 文档的读写 7.4 分割视图窗口 7.5 多文档的应用程序 7.6 应用实例Visual C+程序设计与应用教程57第57页,共298页。7.1 文档/视图结构 为了统一

23、和简化数据处理方法,Microsoft公司在MFC中提出了文档/视图结构的概念。把数据管理和显示方法分离开来,需要考虑: 程序的哪一部分拥有数据程序的哪一部分负责更新数据如何以多种方式显示数据如何让数据的更改有一致性如何储存数据(放到永久储存装置上)如何管理使用者接口。58第58页,共298页。7.1.1 概述文档/视图结构的基本概念及创建过程。 (以例 2.1为例)1.文档(Document) 在文档/视图结构中,文档是用来管理和组织数据的。CDocument类支持文档的标准操作,为了在应用程序中处理文档,首先应该从CDocument类派生出一个属于自己的文档类,并且在类中声明一些成员变量,

24、用来存放数据;然后完成读取和修改文档数据的成员函数;最后再至少重载专门负责文件读写操作的Serialize( )函数。59第59页,共298页。 在使用MFC创建新的应用程序框架时,AppWizard准备好了文档类的空壳,下面是应用程序Li2_1中文档类的定义的部分代码:/ Li2_1Doc.h : interface of the CLi2_1Doc classclass CLi2_1Doc : public CDocument/派生出一个属于自己的文档类protected: CLi2_1Doc(); DECLARE_DYNCREATE(CLi2_1Doc)public: virtual B

25、OOL OnNewDocument(); virtual void Serialize(CArchive& ar); /专门负责文件I/O的函数;60第60页,共298页。2视图 (View) 在文档/视图结构中,视图的作用是显示和编辑文档数据,提供用户与文档数据的交互接口。视图在MFC的CView类里被实例化。 在开发应用程序时,应该从CView类派生出一个属于自己的视图类,并且在类中至少改写专门负责显示数据的OnDraw()函数或OnPrint()函数。61第61页,共298页。class CLi2_1View : public CView /派生出一个属于自己的视图类protected:

26、 / create from serialization only CLi2_1View(); DECLARE_DYNCREATE(CLi2_1View)public: CLi2_1Doc* GetDocument(); /得到与之相关联的文档对象的指针public: virtual void OnDraw(CDC* pDC); / 负责显示数据的OnDraw()函数 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtu

27、al void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);public: virtual CLi2_1View();;62第62页,共298页。 CView类和它的9个派生类封装了视图的各种不同的功能,它们为用户实现最新的Windows特性提供了很大的便利。这些派生视图类也可以作为用户程序中视图类的基类,而将这些视图类设置为基类的最基本的方法是在MFC APPWizard创建SDI/MDI的第6步中进行基类的选择。这些视图类如下表所示

28、。63第63页,共298页。64第64页,共298页。 Frame窗口负责文档与视图的界面管理,当Frame窗口关闭时,在其中的视图也被自动删除。下图说明了文档、视图、框架窗口之间的关系。3. 框架 (Frame) 窗口一个视图只能拥有一个文档,但一个文档可以同时拥有多个视图。 65第65页,共298页。4.文档模板(Document Template) 文档模板定义了文档、视图和框架窗口这3个类的关系。 MFC提供了一个文档模板类CDocTemplate支持文档模板。文档模板类是一个抽象的基类,它定义了文档模板的基本处理函数接口。由于它是一个抽象基类,因此不能直接用它来定义对象而必需用它的派

29、生类。对一个单文档界面程序,使用CSingleDocTemplate类,而对于一个多文档界面程序,使用CMultipleDocTemplate类。 66第66页,共298页。5文档/视图结构的产生 一般在应用程序的初始化函数InitInstance()中创建一个和多个文档模板。67第67页,共298页。BOOL CLi2_1App:InitInstance() CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CLi2_1Doc), RUNTI

30、ME_CLASS(CMainFrame), RUNTIME_CLASS(CLi2_1View);AddDocTemplate(pDocTemplate);68第68页,共298页。文档/视图结构的创建过程如下图所示。 69第69页,共298页。7.1.2 文档与视图之间的相互作用 文档与视图的交互是通过类的公有成员变量和成员函数实现的。1视图类CView的成员函数GetDocument() 一个视图对象只有一个与之相关联的文档对象。在MFC应用程序中,视图对象通过调用成员函数GetDocument()得到与之相关联的文档对象的指针,利用这个指针就可以访问文档类及其派生类的公有数据成员和成员函数

31、。70第70页,共298页。2CDocument类的成员函数UpdateAllViews() 一个文档对象可以有多个与之相关联的视图对象,但一个文档对象只反映当前视图的变化。当一个文档数据通过某个视图被修改后,与它关联的每一个视图都必须反映出这种修改。因此,视图在需要时必须进行重绘,即当文档数据发生改变时,必须通知所有相关联的视图对象,以便更新所显示的数据。更新与该文档有关的所有视图的方法是调用成员函数CDocument:UpdateAllViews()。 71第71页,共298页。3视图类的成员函数OnUpdate() 当应用程序调用CDocument:UpdateAllViews()函数时

32、,实际上是调用了所有相关视图的OnUpdate()函数,以更新相关的视图。需要时,可以直接在视图派生类的成员函数中调用该函数刷新当前视图。另外,在初始化视图成员函数CView:OnInitialUpdate()中也调用了OnUpdate()函数。 刷新视图时默认的函数调用过程是:Cdocument:UpdateAllViews()CView:OnUpdate()CWnd:Invalidate()OnPaint()OnDraw()。72第72页,共298页。4CView类的OnInitialUpdate()函数 当应用程序被启动,或用户从“文件”菜单中选择了“新建”或“打开”命令时,CView的

33、OnInitialUpdate()函数会被调用,该函数是虚函数。 还可以利用派生类的OnInitialUpdate()函数对视图对象进行初始化。当应用程序启动后,应用程序框架在调用了OnCreate()函数后(如果对OnCreate()函数进行了映射),会立即调用OnInitialUpdate()函数。OnCreate()函数只能被调用一次,而OnInitialUpdate()函数则可以被调用多次。73第73页,共298页。7.1.3 使用文档视图结构的意义74第74页,共298页。文档视图结构带来的好处主要有:首先是将数据操作和数据显示、用户界面分离开 MFC在文档/视图结构上提供了许多标准

34、操作界面,包括新建文件、打开文件、保存文件、打印等,减轻了用户的工作量支持打印预览和电子邮件发送功能75第75页,共298页。7.2 简单的文档/视图结构应用程序 一般的,类的数据成员的初始化都是在构造函数中完成的,在构造函数调用结束时对象才真正存在。但对于文档来说却不同,文档类的数据成员初始化工作是在OnNewDocument()成员函数中完成的。7.2.1 文档中数据的初始化76第76页,共298页。7.2.2 文档中数据的清理 同文档的初始化类似,文档的清理也不是在文档的析构函数中完成,而是在文档的DeleteContents()成员函数中完成的。77第77页,共298页。7.2.3 简

35、单的文档/视图结构应用程序 【例7.1】编写一个单文档的应用程序Mydraw,程序运行后,当用户在客户区窗口按下鼠标左键时,以鼠标所在位置为圆心绘圆。78第78页,共298页。 编译、链接并运行程序。在视图窗口中单击鼠标左键,就可以鼠标所在位置为圆心绘圆。绘制的图形符合题目要求,但当改变窗口大小或将窗口最小化后再重新打开,原来的圆没有显示出来。其原因是此时调用的是视图类的刷新函数OnDraw(),而在该函数中并没有实现绘圆功能。79第79页,共298页。 为了避免上述情况的发生,必须在OnDraw()函数中重绘以前单击鼠标所绘制的圆,因此需要将鼠标单击时的坐标数据保存起来。 下面的例7.2在文

36、档类中定义一个大小为100的points数组来保存圆心坐标数据。80第80页,共298页。【例7.2】完善例7.1应用程序Mydraw,在重绘窗口时能够显示已绘制的圆。81第81页,共298页。7.2.4 集合类的使用 通常使用简单的数组或链表来存储集合数据。MFC提供了相应的集合类,来实现数组、列表和映象操作。数组类类似于标准的C数组,允许使用下标访问和操作数组元素,MFC数组类还可在需要时,动态地缩减和增加数组所需的内存空间。列表类就是一个有序元素列表,提供用于在任意地方插入和删除节点,向前、向后遍历元素的功能。映象类是使用关键字进行访问的对象的集合,类似于字典的组织方式,通过使用哈希(h

37、ashing)技术来使映象值与关键字配对,能实现对项目的快速访问。82第82页,共298页。MFC提供了两种集合类:基于模板的集合类 由这些集合类可以创建任何类型的数组、列表和映象。为了使用这些类,必须在程序中包含头文件“afxteml.h”。非模板集合类 MFC提供了许多预定义的类,分别用来实现特定类型的数组、列表和映象。83第83页,共298页。 各个模板集合类的使用方法与对应的数组类、链表类、映射类的使用方法相同,只需在定义具体的数组类对象或链表类对象、映射类对象时给模板实例化,指定一个具体的类即可。例如下面的语句定义了一个CPtrArray类对象:CStringArray m_strT

38、ext 而下面的语句定义了一个CTypedPtrArray类对象:CTypedPtrArray m_CircleArray84第84页,共298页。【例7.3】编写一个单文档的应用程序Mycircle,利用数组类实现例7.2的功能。85第85页,共298页。7.3 文档的读写 MFC中提供了一种读写文件的简单方法“序列化”(即Serialize ,该函数为虚函数)。 序列化机制通过更高层次的接口功能向开发者提供了更利于使用和透明于字节流的文件操纵方法。 序列化也叫串行化。86第86页,共298页。7.3.1 MFC文档读写机制1创建文档2打开文档87第87页,共298页。3保存文档88第88页

39、,共298页。4关闭文档 当用户试图关闭文档(或退出应用程序)时,应用程序会根据用户对文档的修改与否 来进一步完成下列任务:(1) 若文档内容已被修改,则弹出一个消息对话框,询问用户是否需要将文档保存。若用户选择“是”,则应用程序执行OnFileSave()过程。(2) 调用CDocument:OnCloseDocument()虚函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类CDocument的DeleteContents()清除文档数据。89第89页,共298页。序列化的基本思想是: 一个类应该能够对自己的成员变量的数据进行读写操作,对象可以通过读操作而重新创建。即对象可以将

40、其当前状态(由其成员变量的值表示)写入永久性存储体(通常是指磁盘)中,以后可以从永久性存储体中读取(载入)对象的状态,从而重建对象,类的对象自己应该具备将状态值写入磁盘或从磁盘中读出的方法(即成员函数),这种对象的保存和恢复的过程称为序列化。7.3.2 MFC文档序列化90第90页,共298页。 MFC AppWizard向导生成的Seralize()函数由一个if-else结构组成,例如应用程序Li7_1中有如下代码:void CLi7_1Doc:Serialize(CArchive& ar) if(ar. IsStoring ( ) ) /写数据 / TODO:add storing co

41、de here. else /读数据 / TODO:add loading code here. 91第91页,共298页。 【例7.4】继续完善例7.2的应用程序Mydraw,以便能将绘制好的图形保存在磁盘上。92第92页,共298页。 7.3.3 自定义可序列化的类要让用户定义的类支持序列化,必须满足以下5个条件:(1)从CObject类派生,这样派生类就具有RTTI(Run-time type information)、Dynamic Creation等功能。(2)类的声明部分必须有DECLARE_SERIAL宏,此宏需要1个参数:类名称。(3)类的实现部分必须有IMPLEMENT_SE

42、RIAL宏,此宏需要3个参数:一是类名称,二是基类名称,三是版本号。93第93页,共298页。(4) 重新定义Serialize( )虚函数,使它能够适当地把类的成员变量写入文件中。(5) 为此类加上一个默认构造函数,这是因为如果一个对象来自文件,MFC必须先动态地创建它,而且在没有任何参数的情况下调用构造函数,然后才从文件中读取对象数据。94第94页,共298页。【例7.5】完善例7.3的应用程序Mycircle,利用序列化来保存文件,并使自定义类支持序列化。95第95页,共298页。7.4 分割视图窗口分割窗口分为两类:动态分割窗口和静态分割窗口。动态分割窗口是指:用户可以动态的分割和除去

43、分割窗口,分割窗口会创建和删除相应的窗格。静态分割窗口是指:在窗口创建时,分割窗口的窗格就已经创建好了,且窗格的数量和顺序不会改变。窗格为一个分割条所分割,用户可以拖动分割条调整相应的窗格的大小。96第96页,共298页。7.4.1 CSplitterWnd类 类CSplitterWnd是MFC类库中实现分割窗口的基类,根据需要可以从该类派生自己的分割窗口类。 分割窗口是含有多个窗格的窗口,每个窗格通常是应用程序特定的由CView派生类的对象,也可以是具有适当子窗口ID的任何CWnd对象。 类CSplitterWnd是类CWnd的派生类。97第97页,共298页。7.4.2 分割视图窗口的实现

44、技术1. 动态分割窗口 动态分割窗口是调用create()成员函数创建的,通常用于创建和滚动同一文档的多个窗格或视图,此处窗格或视图属于同一个类的窗格或视图。98第98页,共298页。【例7.6】 创建一个一行两列窗格的动态分割窗口的单文档应用程序Li7_6。99第99页,共298页。2静态分割窗口 静态分割窗口是调用CreateStatic()成员函数创建的,通常用于创建同一文档的多个不同窗格或视图,而这里的多个窗格或视图往往是属于不同类,这些窗格在我们创建分割器时就必须各个创建,通常使用CreateView()函数创建窗格。100第100页,共298页。【例7.7】创建一个一行两列窗格的静

45、态分割窗口的单文档应用程序Li7_7,其中左窗格是一个CFormView格式视用于选择画线、矩形、圆,右窗格是一个CView视响应这些选择用于画线、矩形、圆,如图7.10所示。101第101页,共298页。7.5 多文档的应用程序7.5.1 多文档应用程序的界面102第102页,共298页。7.5.2 多视图的应用程序 文档与视图分离使得一个文档对象可以和多个视图相关联,这样可以更容易实现多视图的应用程序。如Excel制表程序能够对表格数据采用多种视图来显示,可以是网络状表格,也可以是条形表格。同一份文档数据可以用文字表示,也可以用图形表示。只要具备MDI性质,MFC应用程序就具备了“多视图”

46、功能。虽然说静态分割窗口的窗口可视为完全独立的View窗口,但它们毕竟不是!它们还框在一个大窗口中。事实上,MDI不仅可以在同一时间内同时打开多个文档,还可以为同一文档打开多个视图。在Windows菜单下选择New,就为当前活动文档打开一个新的子窗口。 103第103页,共298页。【例7.9】编写一个MDI应用程序Li7_9,当执行【窗口|斜体窗口】菜单命令时重新打开一个窗口,并以斜体方式显示一个文档的内容。104第104页,共298页。7.5.3 多类型的应用程序 事实上,多文档应用程序除了支持单一文件类型外,还可以支持多种文件类型,即一个应用程序可以处理多种文件格式,105第105页,共

47、298页。【例7.10】 建立一个多类型文档的应用程序Li7_10,该应用程序能显示两种类型的窗口,一种输出文本,在另一种窗口中,可以输出图形。同时根据不同的文件类型,显示不同的菜单。106第106页,共298页。7.6 应用实例 编写一个简单的文本编辑器,以此说明文档/视图结构的原理及应用。在该编辑器中,用户只能完成字符的逐行输入、通过回车键换行、为文本选择字体及颜色等简单功能。107第107页,共298页。第 8 章 打印编程 8.1 基本打印功能 8.2 设置打印坐标系 8.3 多页打印 8.4 高级打印Visual C+程序设计与应用教程108第108页,共298页。8.1 基本打印功

48、能 在使用应用程序向导(AppWizard)生成应用程序的过程中,如果在第四步不取消对打印和打印预览的设置,那么应用程序就已经具备了简单的打印和打印预览功能。109第109页,共298页。8.1.1 打印原理 在文档/视图结构应用程序,CDocument类负责数据的生成和储存,CView类负责数据的显示和用户交互。输出到屏幕和输出到打印机都是数据的显示,实质上是一样的,因此打印功能也是由CView类来实现的。110第110页,共298页。111第111页,共298页。 默认的函数Cview:OnPrint( )中只是调用成员函数OnDraw( ),而没有进行其他操作。在以前的程序中,并不考虑打

49、印问题,因此我们只需考虑在OnDraw()中如何完成屏幕输出工作。但现在在OnDraw()中添加代码时,就必须小心这有可能是在进行打印,并不仅向一个窗口输出。如果这两个函数在程序中不能统一,就必须分开考虑。分开考虑时有两种方法:(1) 分别在OnPaint()和OnPrint()这两个函数中完成屏幕输出和打印输出工作,而不必依赖于OnDraw()函数。(2) 在OnDraw()函数中,调用pDC-IsPrinting()或设置变量来识别目前进行的输出工作并区别对待。 112第112页,共298页。【例8.1】编写一个单文档应用程序MyPrint,实现简单的打印功能。113第113页,共298页

50、。 应用程序的【File】菜单条中自动添加【打印】、【打印预览】和【打印设置】3个菜单项。应用程序基本打印功能的实现主要是由消息映射宏和消息处理函数完成的。114第114页,共298页。(1) 在应用程序视图类CMyPrintView的消息映射宏中包含了以下打印和打印预览命令的消息映射代码:BEGIN_MESSAGE_MAP(CMyPrintView, CScrollView) / Standard printing commands ON_COMMAND(ID_FILE_PRINT, CScrollView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRE

51、CT, CScrollView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView:OnFilePrintPreview)END_MESSAGE_MAP()115第115页,共298页。(2)在CMyPrintApp类的消息映射宏中包含了打印设置的以下消息映射代码:BEGIN_MESSAGE_MAP(CMyPrintApp, CWinApp)/ Standard file based document commandsON_COMMAND(ID_FILE_NEW, CWinApp:OnFileNew)ON_COMMAND(ID_

52、FILE_OPEN, CWinApp:OnFileOpen)/ Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp:OnFilePrintSetup)END_MESSAGE_MAP()116第116页,共298页。(3) 在CMyPrintView.cpp文件中由系统自动生成了以下3个函数:BOOL CMyPrintView:OnPreparePrinting(CPrintInfo* pInfo)/ default preparationreturn DoPreparePrinting(pInfo);void

53、 CMyPrintView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: add extra initialization before printingvoid CMyPrintView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: add cleanup after printing117第117页,共298页。8.1.2 CPrintInfo类 CPrintInfo类保存了打印和打印预览的相关信息,当用户单击【File】菜单的【打印】或【打印预览

54、】命令时,系统自动创建一个CPrintInfo类对象,用于保存用户打印设置的信息。当打印操作结束时,系统自动删除CPrintInfo类对象。在打印过程中,CPrintInfo类在框架窗口和CView类之间起着消息传递的作用。118第118页,共298页。8.1.3 打印过程 一个打印作业由以下几步构成:(1)如果执行打印预览命令,框架窗口将调用CView:OnPreparePrinting()函数,创建与当前默认打印机相关的设备描述对象,对CPrintInfo类中的一些成员变量赋值或调用类成员函数来控制打印的方式,调用DoPreparePrinting()函数。 如果执行打印命令,DoPrep

55、arePrinting()函数将显示打印对话框。在对话框中,用户可 以设置打印范围,选择打印机、打印份数。119第119页,共298页。(2)调用CView:OnBeginPrinting()函数分配打印过程所需要的系统资源。(3)调用CDC:StartDoc()启动主打印循环。(4)打印新页时,框架窗口首先调用CView:OnPrepareDC(),在打印之前根据当前打印机的设备描述表进行调整。 如果事先不知道需要打印多少页,则被重载的OnPrepareDC()函数可以检测文档的结束。如果文档结束,将CPrintInfo:m_bContinuePrinting值设置为FALSE,跳到(6);

56、否则,设置CPrintInfo:m_bContinuePrinting的值为TRUE,继续进行打印。120第120页,共298页。(5) 调用CDC:StartPage()、CView:OnPrint()和CDC:EndPage()进行打印。在默认情况下,OnPrint()函数首先调用OnPrepareDC()函数对坐标进行变换,然后调用OnDraw()函数往打印机里输出数据。(6) 当m_bContinuePrinting为FALSE时,打印结束。调用CDC:EndDoc()函数释放在 打印过程中占用的各种资源。(7) 调用OnEndPrinting()函数,结束打印。121第121页,共2

57、98页。122第122页,共298页。8.1.4 打印预览 打印预览命令的执行可以分成以下几个步骤:主框架窗口执行OnFilePreparePrint()函数。在OnFilePreparePrint()函数中,执行 OnPreparePrinting(CPrintlnfo*pInfo)函数,检测m_bPreview变量是否为TRUE。如果是,则对CPrintInfo类中的一些成员变量赋值或调用类成员函数来控制打印预览的方式。调用CView:DoPreparePrinting()函数,显示打印预览界面。调用OnDraw()函数按照打印机的设备描述表往屏幕输出数据,利用屏幕来模拟显 示打印结果。1

58、23第123页,共298页。8.2 设置打印坐标系8.2.1 Windows映射模式 Windows映射模式就是Windows下的坐标方式。在Windows操作系统中,存在两种类型的坐标:设备坐标和逻辑坐标。当向设备输出图形时,Windows先映射当前逻辑坐标到物理坐标(例如打印机),然后显示图形输出。124第124页,共298页。125第125页,共298页。8.2.2 映射模式的设置 在MFC应用程序中,通过调用CDC类的SetMapMode()函数设置映射方式。如在视图类的OnDraw()函数中,可以通过以下代码设置映射方式:pDC- SetMapMode(n);其中,n为上表中列出的映

59、射方式。126第126页,共298页。【例8.2】完善例8.1中的程序MyPrint,使打印输出的图形与显示器显示的图形大小基本一样。 127第127页,共298页。8.3 多页打印8.3.1 默认打印存在的不足【例8.3】完善例8.2中的程序MyPrint,程序运行后,屏幕上能显示50个矩形。128第128页,共298页。8.3.2 实现多页打印功能 如果要使程序支持多页打印功能,首先在打印之前设置要打印的页数,然后设置每一页视图原点的打印坐标。1设置要打印的页数 一般在OnBeginPrinting()函数中设置要打印的页数,通过CPrintInfo类的SetMaxPage()和SetMi

60、nPage()函数实现。129第129页,共298页。【例8.4】完善例8.3中的程序MyPrint,设置要打印的页数130第130页,共298页。2设置正确的视图原点 为了正确打印每一页,需要设置每页打印的内容对应于坐标的那一部分区域。第一页视图原点的打印坐标为0,第二页视图原点的打印坐标下移一个页的高度,依此类推。 可以在OnPrepareDC()函数中通过调用CDC类成员函数SetViewPortOrg( )设置当前页的视图原点坐标。由于这些设置在OnPrint()和OnDraw()都起作用,既影响打印又影响显示器显示,因此必须调用CDC类的成员函数IsPrinting()来判断当前状态

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论