




已阅读5页,还剩148页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三章MFC程序设计,本章的内容,简洁而不失完整性:由应用程序向导建立程序框架,由资源编辑器建立用户界面,由类向导建立成员变量、消息映射和处理函数,加上文档序列化和注册MFC包含了所有与系统相关的类(包括图形用户界面相关的类),其中封装了大多数的API函数,提供了应用程序框架和开发应用程序的工具如应用程序向导、类向导、可视化资源设计等高效工具,用消息映射处理消息响应,大大简化了Windows应用程序的开发工作,使程序员可以从繁重的编程工作中解脱,提高工作效率。,3.1.MFC程序设计简介3.2.MFC程序设计3.3.用户界面资源的应用3.4.对话框的应用3.5.基于对话框的应用程序设计实例3.6.文本和图形输出3.7.文档的保存3.8.MDI应用程序设计,目录,3.1MFC程序设计简介,MFC类库基础类(已在第二章中介绍)宏、全局变量及全局函数应用程序框架,3.1.1MFC定义的宏、全局函数及全局变量,类库,1.MFC提供的主要宏:,消息映射宏:声明消息映射表宏DECLARE_MESSAGE_MAP、消息映射定义宏BEGIN_MESSAGE_MAP和END_MESSAGE_MAP消息映射表入口宏ON_消息名。(本章只介绍消息映射宏),3.1.1MFC定义的宏、全局函数及全局变量,动态MFC对象宏DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC动态创建对象宏DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE运行时类宏:RUNTIME_CLASS序列化宏:DECLARE_SERIAL和IMPLEMENT_SERIAL诊断服务宏:ASSERT、VERIFY跟踪服务宏:TRACE异常处理宏:THROW,3.1.1MFC定义的宏、全局函数及全局变量,MFC提供一些不属于任何类的全局函数,函数名以Afx开头,可以被应用程序中的所有类和函数所调用。如:AfxAbort(),无条件终止一个应用程序的执行;AfxGetAppName(),返回指向应用程序名的字符串指针;AfxWinInit(),由WinMain()调用,对MFC应用程序进行图形用户界面(GUI)的初始化等等。,3.全局变量,全局变量名以afx开头,如afxTraceFlag、afxDump等,主要与异常处理有关。,2.全局函数,3.1.2MFC命名规则,匈牙利命名法规定:,变量名以一个或多个小写字母开头作为前缀,标识变量的数据类型;,类型标识后是若干个单词,标识变量含义,每个单词以大写字母开头,其余字母小写;,MFC中所有类及自定义类都以C开头;,类成员变量以m_为前缀,下划线后是变量名等等。,表3.1命名规则,h,MFC提供了构造Windows应用程序的框架,它不仅为应用程序建立标准的结构,生成一系列起动文件,还提供标准的图形用户界面如菜单、工具栏、状态条等供开发人员在程序中补充完善,开发人员只需要完成针对特定应用的代码。使用应用程序框架的应用程序代码小,运行速度快,它提供的工具也降低了编码的难度。,3.1.3应用程序框架介绍,程序的数据储存在文档类中(作为文档类的数据成员),是对数据的抽象表示。数据显示由视图负责,视图是程序窗口的客户区,框架窗口是客户区的框架,程序数据显示在窗口,用户通过视图与程序交互。一个文档可以对应多个不同视图;而一个视图一般只对应一个文档。当文档数据发生变化时,视图显示的状态也会随之变化;对于多个视图的情况,基于同一文档的多个视图的显示同步变化。,1.文档-视图结构,文档视图结构提供一种连续处理数据的方式,使应用程序的数据与数据的显示分开处理。,文档、视图及框架的关系:,图3.1,2.单文档界面应用,单文档界面应用程序简称SDI(SingleDocumentInterface),只允许一个框架窗口存在,每次只能创建和拥有一个文档对象,也只允许打开一个文档。SDI各类关系图,可将文档比作一个文件袋,专门用于保存文件数据,需要看时需从文件袋(文档)中取出来,放到桌面(视图)上看。,表3.2基于文档/视图关系的SDI应用中的类,返回,应用程序类,框架类(窗口框架),资源(决定用户界面的显示),视图类(显示数据并与用户交互),文档类(保存数据),单文档模板,返回,应用程序类CDocManager*m_pDocManager,框架类(窗口框架),资源(决定用户界面的显示),m_pDocument视图类(显示数据并与用户交互),文档类(保存数据)m_pDocTemplatem_viewList,返回,单文档模板CRuntimeClass*m_pDocClassCRuntimeClass*m_pFrameClassCRuntimeClass*m_pViewClassUINTm_nIDResource,多文档界面应用简称MDI(MultipleDocumentInterface),允许有多个文档类、视图类和多个文档模板CMultiDocTemplate(建立多种文档-视图-子框架关系)存在,运行时允许打开多个MDI子框架窗口,拥有各自的文档和视图对象。示例关系图,在打开的多个子窗口中,只有一个活动窗口,应用程序菜单和工具栏的所有的命令都是针对活动窗口的。,3.多文档界面应用,主框架,其它文档模板,返回,CDocManager,应用程序类CDocManager*m_pDocManager,文档/视图结构可以充分发挥应用程序框架和MFC的优势,是MFC应用程序的核心,但使用它也要付出运行效率和代码增大的代价。,文档/视图结构对应用程序来说并不是必不可少的,有两种常见的非文档/视图结构应用。,4.非文档/视图结构应用,常见非文档/视图结构应用:,(1).基于对话框的应用,它包含一个CWinApp对象和一个模态对话框,对话框负责数据的存储和显示。关系图,(2).SDI或MDI应用,都可以不包含文档对象,SDI包含一个CWinApp对象,一个框架窗口对象和一个从CWnd派生的CChildView视图对象,视图对象负责数据的显示,MDI应用还包括一个子框架窗口。,对话框类作为应用程序主窗口负责保存和显示数据,应用程序类,返回,Dialog-basedApplication,主框架,应用程序主窗口,CChildView视图类负责保存和显示数据,应用程序类,SDIApplication,NoneDoc/View,返回,子框架,视图框架窗口,CChildView视图类,应用程序类,子框架,视图框架窗口,CChildView视图类,主框架,应用程序主框架窗口,MDIApplication,NoneDoc/View,返回,图3.2MFC应用程序开发过程,类向导,集成开发环境,应用程序向导,资源编辑器,Create,.def,.cpp.h,.dsw.dsp,.ico,.rc,.bmp,源文件,资源文件,编译,.obj,Build,资源编译,.res,应用程序,5.MFC应用程序创建,6.最简单的MFC应用程序示例,对于一个MFC应用程序来说,只有CWinApp的派生对象是必不可少的,其它类均可视情况进行取舍。下例是一个最简单的MFC应用程序。例:显示一个消息框。(1).创建工程,工程类型选择Win32Application,工程名为Ex3_0;(2).创建C+源文件,文件名Ex3_0.cpp,内容如下:,#includeclassCEx3_0App:publicCWinApp/CWinApp派生类public:virtualBOOLInitInstance()MessageBox(NULL,”SimplistMFCApplication.”,”Ex3_0”,MB_OK);returnTRUE;CEx3_0ApptheApp;/全局变量,代表应用程序本身,CWinApp:InitInstance()虚函数完成应用程序的初始化工作,派生的应用程序类都要重载此函数进行初始化,如完成主框架窗口的构造,窗口定义显示等工作。,(3).设置使用MFC。选择Project|Settings菜单项,选择General页面,在MicrosoftFoundationClasses组合框中选择UseMFCinasharedDLL。(4).编译生成并运行此工程,结果显示一个消息框,如下图:,图3.3最简单MFC应用示例,3.2.MFC程序设计,MFC应用程序的执行过程(参见图3.4):,1.构造全局对象CWinApp派生类对象;,2.运行由应用程序框架提供的WinMain函数;,图3.4MFC应用程序的执行过程,3.在WinMain中,通过afxGetApp()获得全局对象的指针pApp,调用全局函数AfxWinInit(),为CWinApp的成员变量m_hInstance,m_hPrevInstance,m_lpCmdLine,m_nCmdShow赋初值;然后调用pApp-InitApplication(),这是CWinApp的虚函数,一般不需要改写;调用pApp-InitInstance(),每个程序都必需改写这个函数,进行应用程序初始化;,4.在InitInstance()函数中,先用new构造一个CFrameWnd派生类对象,其构造函数又调用Create(),创建主窗口,MFC依此自动为应用程序注册窗口类;调用ShowWindow()显示窗口,调用UpdateWindow(),发出WM_PAINT消息;,5.回到WinMain中,调用pApp-Run,进入消息循环,通过API函数GetMessage()获得消息,TranslateMessage()处理消息,DispatchMessage()派送消息到CWnd:DefWindowProc(),DefWindowProc()按照消息映射表的定义将消息分发到各相应消息处理函数;如消息队列为空,则Run调用CWinApp:OnIdle()进行空闲处理,重载OnIdle()可以去处理后台程序(低优先级);,6.若用户选择菜单File/Close,则程序收到WM_COLSE消息,调用:DestroyWindow()发出WM_DESTROY消息,然后调PostQuitMessage(),发出WM_QUIT消息,此时Run会结束其内部消息循环,调用ExitInstance();,7.最后,返回WinMain(),执行WinTerm(),结束程序运行。,几点解释:,(1).每个MFC应用都有stdafx.h头文件,由应用程序向导自动生成;,(2).每个MFC应用都应包含头文件afxwin.h,其内部又包含了其他头文件。,(3).每一个MFC应用程序都包含唯一的CWinApp派生类对象,代表应用程序本身。,(4).MFC应用程序中看不到WinMain()入口函数,它被封装在应用程序框架里,运行时自动调用;,3.2.2.MFC消息映射,消息映射(MessageMap)机制:消息映射机制规定每个要响应消息的类定义自己的消息映射表,将消息与处理消息的函数联系在一起;当事件发生产生消息时,在程序中各个类的消息映射表中查找,当找到消息处理函数时,便将消息送至对应的消息处理函数进行处理。每个从CCmdTarget所派生的类都可以接收消息,都可以定义自己的消息映射表MessageMap。,消息映射表:,1.消息消息是Windows用来通知MFC应用程序事件发生的主要方式,应用程序的行为取决于对消息的响应方式。MFC把消息分为三大类:(1).标准Windows消息(WM_XXX),(2).命令消息(WM_COMMAND),(3).控件通知消息。,2.消息映射消息映射将消息与应用程序提供的处理该消息的成员函数联系在一起,一组消息映射构成消息映射表。消息映射表由BEGIN_MESSAGE_MAP和END_MESSAGE_MAP这一对宏作开始和结束,中间是若干消息映射入口每一个入口由特定的消息宏ON_XXX组成,将一个消息与与之对应的处理函数联系在一起。,定义和使用消息映射表的步骤:,在头文件的类声明中添加DECLARE_MESSAGE_MAP宏声明消息映射;例如,在类的定义文件(.cpp)定义消息映射表,方法是在文件的开始处添加BEIGN_MESSAGE_MAP和END_MESSAGE_MAP这一对宏,在它们之间放置消息映射宏,定义并初始化消息映射表,在消息与处理消息的函数之间建立联系;例如,在类的定义文件(.cpp)中添加消息处理函数。例如,消息宏:(1).对标准Windows消息的响应,消息宏ON_WM_XXX定义对标准Windows消息WM_XXX的响应,所有派生自CWnd的类均可响应这类消息,系统默认的响应函数为OnXxx,对应关系见下面的表3.3:,由于有系统默认的消息和处理函数,在消息映射表中只写宏名,如:ON_WM_CREATE(),(2).对命令消息的的响应。,ON_COMMAND宏定义对命令消息的响应,格式为ON_COMMAND(命令ID,响应函数)举例如下:ON_COMMAND(IDM_ABOUT,OnAbout)/表示IDM_ABOUT消息由OnAbout()响应ON_COMMAND(IDM_FILENEW,OnFileNew)ON_COMMAND(IDM_FILEOPEN,OnFileOpen)所有由用户定义的命令消息也由ON_COMMAND定义消息映射关系。,(3).对控件消息的响应,控件消息由按钮(BN_)、编辑框(EN_)、组合框(CBN_)、列表框(LBN_)等产生,在消息名前加上ON_即构成宏名,举例如下:ON_BN_CLICKED(按钮ID,响应函数)ON_CBN_DBCLK(组合框ID,响应函数)ON_EN_SETFOCUS(组合框ID,响应函数)ON_LBN_DBCLK(列表框ID,响应函数)分别表示选择各个控件后,产生的消息由其后面定义的函数进行处理。,3.消息处理消息一般由应用程序中对象的成员函数来响应。当某个事件发生后,系统向应用程序消息队列放入一个消息,CWinApp对象取得消息并按照消息映射表的定义将消息派送到某个类的相应的消息处理函数进行处理。使用ClassWizard(见第五章菜单中View菜单介绍)定义消息映射关系,添加消息处理函数,系统会自动生成函数原型和函数框架,开发人员只要添加函数体代码,可以避免一些常见错误的产生。,程序中类响应windows消息的优先顺序:取决于消息传递的顺序。对于一般的Windows消息,由产生这些消息的对象响应,如窗口的创建WM_CREATE,窗口的移动WM_MOVE,由产生消息的窗口类响应,如果找不到相应的处理函数,则将消息传递到其父类,一般情况都有缺省的响应函数;对于命令消息WM_COMMAND,可由拥有菜单资源的所有类来处理,传递的顺序是视图类、文档类、文档模板类、框架类、应用程序类,即这些类处理命令消息的优先顺序。详见第2章。,视图类的定义文件(.cpp)中必须有消息映射定义:BEIGN_MESSAGE_MAP(CMyView,CView)/消息映射表定义ON_WM_LBUTTONDOWN()/函数名为OnLButtonDown/其它消息映射入口END_MESSAGE_MAP()以及对应的消息响应函数定义:voidCMyView:OnLButtonDown(UINTnFlags,CPointpoint)/处理消息的操作代码,程序中具体实现返回,将CMyView的基类CView也包含进去,当在派生类中没找到处理函数时,允许在基类中继续查找。,注,例如,当用户在视图窗口中按下鼠标左键时,Windows发送WM_LBUTTONDOWN消息到应用程序,假设视图类需要响应这些消息,在类的头文件(.h)中有函数声明和消息映射表的声明:ClassCMyView:publicCViewafx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);/函数原型声明DECLARE_MESSAGE_MAP()/消息映射表声明返回,afx_msg标识消息映射函数,所有由ClassWizard生成的消息处理函数原型说明前都有这一标识。,注,3.2.3.文档/视图结构,1.文档类在基于文档/视图结构的应用程序中,CDocument的派生对象负责读入、保存和管理应用程序的数据。每个文档类可能与多个视图类关联,而每个视图包含一个指向与其相关的文档的指针。文档类允许向其中增加数据成员,应用程序的数据可以是任何类型的,或者是任何自定义的数据结构,如结构体,类或链表等。,3.2.3.文档/视图结构,文档类的常用成员函数(带的表示是可重定义函数),表3.4,2.视图类,视图类对象代表了应用程序的窗口客户区,是文档信息的一个显示窗口(视口),它同时也是用户与程序之间信息交互的桥梁,用户对数据的编辑和修改需要通过键盘或鼠标进行,这些消息都由视图类接受后再反映到文档类。,视图类的派生关系:,图3.5,CView类提供了向视图或打印机进行输出的基本框架,决定了视图的基本特性,派生的视图类可以重载基类的函数,或增加新的函数以决定特定视图的特性。CView的派生类可以多种方式显示文档类的信息,每个视图类根据显示的方式各自定义其显示代码。MFC提供了一系列这样的类,如CTreeView树型视图CListView列表型视图CFormView显示基于对话框模板的视图CScrollView带滚动条的视图。,1)视图类实现特定视图的特性的虚函数,表3.5,CEx3_1Doc*pDoc=GetDocument();通过GetDocument获得与视图关联的文档类指针,通过指针pDoc访问文档类的数据成员和函数成员,在视图(窗口)中显示文档对象,当用户通过视图改变文档数据时,可设置自动更新文档内容。文档/视图结构已经把应用程序所需要的数据处理与显示(虚函数)的框架构造好,程序设计人员只需要将具体应用的数据添加到文档类,并根据数据类型在视图类的虚函数OnDraw()中完成数据的显示。,2)视图类的成员函数访问与其关联的文档类的方式,3.文档模板类,CDocTemplate类将框架、视图、文档对象及应用程序的资源捆绑在一起。应用程序每打开一个文件,至少创建一个文档对象、一个视图对象和一个框架窗口,而文档模板对象负责管理所有这些对象,并将各种相关资源与之联系在一起。在大多数情况下,程序不需要对这个类进行修改。,对于SDI应用,使用CSingleDocTemplate文档模板。对于MDI应用,使用CMultiDocTemplate文档模板。MDI允许有多个文档模板,将不同文档-视图类联系在一起,实现不同文档视图显示关系。,4.应用程序创建过程,使用AppWzard,根据实际需要,选择创建合适的应用程序框架(是否使用文档/视图结构,使用SDI或MDI等)在文档类中添加程序所处理的数据,作为文档类数据成员;在视图类中取得文档数据,以合适的方式在窗口中显示出来,5.应用实例,例3_1:创建一个包含文档/视图结构单文档界面应用的实例,为文档类添加一个字符串数据,在视图窗口显示出来。步骤如下:(1).在File菜单中选择New,如图3.,在Project页面选择MFCAppWizard(exe),在Projectname中输入Ex3_1,并选择合适的路径按OK按钮。,(2).在AppWizardStep1中,如图3.,选择SingleDocument单选按钮,并选中Document/ViewarchitechureSupport复选框,表示使用文档/视图结构,按Finish按钮。显示NewProjectInformation信息框,显示新创建的工程的有关信息按OK按钮,这样工程创建完毕。,图3.NewProject对话框,图3.AppWizardStep1,在VC集成开发环境中看到,新工程生成了五个类,如图3.在classview页面上可看到这些类。CAboutDlg派生自CDialog,一个About对话框。CEx3_1App派生自CWinApp,其全局对象theApp代表应用程序本身。CEx3_1Doc派生自CDocument,文档类。CEx3_1View派生自CView,视图类。CMainFrame派生自CFrameWnd,程序框架类。,文档、视图及应用程序类名都以工程名开头,后接对应的类型名,这有助于在程序中有多个文档视图类时区分主视图与其它视图,区分主文档与其它文档类。应用程序向导AppWizard为每个类生成了一个头文件和一个.cpp文件,还自动生成了stdafx.h和stdafx.cpp,图3.,AppWizard还生成了缺省的用户界面资源文件,在Resourceview页面显示。,图3.ClassView,图3.FileView,(3).为文档类增加数据成员。在编辑窗口打开文档类的头文件Ex3_1Doc.h,手工添加一个字符数组成员m_StrName;或在Workspace的ClassView页面,右击CEx3_1Doc类,在弹出式菜单中选择AddMemberVariables,在对话框中输入变量类型和名称。在文档类构造函数中对新增加的变量进行初始化。(4).显示字符串.在CEx3_1View的OnDraw()函数显示字符串。,图3.10例3.1第一步主界面,3.3.用户界面资源的应用,资源是windows应用程序的一种特殊数据,包括菜单、加速键、光标、位图、图标、对话框、字符串、工具栏、状态栏等,资源一般放在exe或DLL文件中。当windows将程序装入内存时,一般不将资源同时装入,而是当需要某个资源时才将相应资源装入。资源定义在资源脚本(resourcescirpt)文件中。以.rc为文件扩展名,文件名与工程名相同。资源脚本文件中定义了各种资源的相关数据,Windows通过使用不同的资源标识符前缀来区分不同资源类型(如表3.所示),这样做虽然不是必须的,但遵循这样的规则有利于提高程序的通用性和可读性。,表3.资源类型及其标示,资源标识前缀IDM_ID_IDI_IDB_IDD_IDR_IDC_IDS_,资源类型菜单项ID菜单命令ID图标ID位图ID对话框ID菜单栏、工具栏、加速键控件ID字符串,返回,VisualC+6.0中提供了资源编辑器,对资源进行可视化编辑,并自动生成资源脚本文件;脚本文件可用文本编辑器进行编辑,但其可读性较差,容易出错,一般情况下尽量不要进行编辑。用户定义的资源标识符号常量定义在resource.h文件中。,3.3.用户界面资源的应用,3.3.1.菜单,分类:顶层菜单:一般位于应用程序主窗口或顶层窗口弹出式菜单:选择某个菜单项后弹出的子菜单,1.菜单的编辑,如果是AppWizard产生的程序,系统已为框架创建了一个标准的主菜单,包括文件、编辑、视图、窗口帮助等标准菜单,定义了各菜单项的ID及相应的命令处理函数。在ResourceView页面,打开工程资源,选择Menu,然后双击主菜单资源IDR_MAINFRAME标示,可打开菜单编辑器。,添加新的菜单资源,选择InsertResource菜单项,在InsertResource对话框中,选择Menu资源类型,单击New按钮,缺省新菜单名为IDR_MENU1。,a)增加一个顶层菜单,在菜单属性对话框中,选中Pop-up选项,可以定义一个顶层菜单,在Caption编辑框中输入菜单名,菜单名即显示在菜单上。若在菜单名的某个字符前加一个/可以向数组中增加ID以增加状态栏上显示栏。,3.3.3状态栏,图3.16例3.1主界面,3.4.对话框的应用,3.4.1对话框的工作方式、种类和创建方法,1.对话框在应用程序中的工作方式,对话框是一个读入或写出数据的图形界面对象,由集成开发环境中的对话框模板提供,可以向模板添加各种控件(如按钮,编辑框,单选复选按钮等),构成程序的对话框资源;,应用程序要使用对话框还需定义一个CDialog派生类的对话框类与资源相连接,并在这个对话框类中定义一些成员变量与对话框中的控件相对应,提供对话框控件的缺省数据值;,程序运行时需要用到对话框时依据对话框资源激活对话框,接收用户输入后通过成员函数更新文档类数据成员,如图3.17示。,图3.17对话框与文档的数据交换,构造对话框并更新文档数据,数据交换,对话框模板controls,public:datamembers,文档类:applicationdatas,对话框类对象,2.对话框的种类,Windows有两种对话框,模态对话框和非模态对话框,构造两种对话框的大多数工作都相同,只是两者的显示和数据处理有些不同。,模态对话框(ModalDialogBoxes)工作时使其父类窗口无效,直到对话框结束。也就是说,该对话框打开后,程序等待用户输入,在关闭对话框后才执行其它任务。,非模态对话框(ModelessDialogBoxes)在打开期间,允许用户切换到程序其它部分,不一定要关闭对话框。WinWord中的FindandReplace对话框是一个典型的非模态对话框。,3.对话框的创建与编辑,a)对话框的创建,选择Insert|Resource.,在InsertResource对话框中选择Dialog类型,按New按钮,打开对话框编辑器,缺省情况下,对话框模板提供了OK和Cancel两个按钮,同时打开了对话框工具栏和控件工具栏,如下图。,图3.18对话框模板及编辑工具,在对话框模板内右击鼠标,在弹出的菜单中选择Properties,打开DialogProperty对话框。,图3.19对话框属性对话框,b)控件属性,将控件工具栏中的任一种控件拖至对话框模板中,在控件上右击鼠标,选择Properties打开控件属性对话框,如图3.20。各种控件属性对话框基本相似,在ID框中输入标识控件的唯一ID值,在Caption中输入控件上显示的字符(Edit控件没有这一属性),Visible表示该控件在对话框创建时是否显示,Group用来控制控件分组,Disabled使控件不可用,Tabstop表示是否用Tab键选择控件。,图3.20控件属性设置对话框,c)控制Tab顺序,当打开对话框编辑器后,集成开发环境的菜单上多了一个Layout菜单,其中主要是对话框工具栏上显示的一些命令,其中有一个命令TabOrder,定义当用户用Tab键移动输入焦点时各控件接受焦点的顺序。如图3.21所示。,d)分组控制,VC提供了根据控件功能将控件进行分组的工具,使用户更易于理解对话框的结构。在分组框中使用最多的是单选按钮(radiobuttons),一组单选按钮允许用户在组内多个相互排他的选项内选择一项。,图3.21设置TabOrder,e)组合框ComboBox,将组合框拖至对话框中后,按向下箭头,显示运行时下拉组合框的大小,调整到合适大小。组合框的属性对话框比其它控件多一个Data页面,用于输入组合框中的数据项,每一行是一项,输完一项按Ctrl+Enter键换行。,f)列表框ListBox,在对话框编辑器中只能设置列表框大小、位置和ID,数据的初始化需要通过编程实现。一般在拥有列表框控件的对话框的OnInitDialog函数中,调用CListBox:AddString(无序)或CListBox:InsertString(有序)插入字符串。,g)测试对话框,当所有控件都布置好并定义属性后,可以选择对话框工具栏上的测试按钮,测试对话框工作情况,必要的话做适当调整。,3.4.2将对话框与程序连结,1.对话框类及数据成员的定义,a)创建对话框类,对话框资源建立好后,在对话框中右击鼠标,选择ClassWizard菜单项,会出现提示框,说明新建的对话框资源是新资源,是否需要建立一个新类或选择一个已存在的类。若选择新类,出现图3.23示的Newclass对话框。选定后,在WorkSpace中可看到新增加的类,自动生成的StudentDlg.h头文件和StudentDlg.cpp源文件。,图3.23新建类对话框,b)增加数据成员,要使对话框能与程序通讯,还需给对话框类增加数据成员,以保存各控件的初始值,并从控件读取数据。与控件对应的数据成员可以是变量或控件类型,如表3.9所示。,表3.9对话框与控件对应的变量或控件数据成员,在ClassWizard的MemberVariables页面,选择对话框类,在ControlIDs中列出了对话框中所有控件ID,如图3.24,选择某个ID,按AddVariable按钮,弹出AddMemberVariable对话框,可输入成员名,在Category中选择值(value)变量或控件(controls)类型,在Variabletype列表框中,若是Value类,选择变量数据类型,若是Controls,选择控件类,按OK,成员添加成功。设计不同的菜单命令响应函数,可以用对话框成员变量更新文档数据;也可以用文档数据为对话框数据成员赋值,再显示对话框,图3.24为对话框添加数据成员,2.对话框的显示,模态对话框调用其DoModal()函数显示,按OK或Cancel按钮关闭对话框非模态对话框调用Create()函数创建并显示对话框用DestroyWindow关闭对话框。,3.为控件添加或修改消息响应函数,打开ClassWizard,在MessageMap页面,可以为控件添加响应函数。如图3.26。,图3.26为控件添加响应函数,图3.27例3.1新主界面,3.5.基于对话框的应用程序设计,AppWizard提供了基于对话框(Dialogbased)的应用程序框架,程序可以简单到只有CWinApp派生类和一个对话框类,对话框就是程序框架,负责数据输入输出和存储,以及消息处理;对话框可以有最小化按钮,甚至可以连接一个菜单。,基于对话框的应用程序结构简单,只要正确选择控件及定义成员变量,设计正确的算法。适合开发数据不多,功能简单的程序。,3.6.文本和图形输出,Windows设备描述表DC(devicecontexts),是对各种不同设备的抽象,应用程序只要向DC输出,由DC负责处理不同设备的差异。,DC是一个数据结构,描述了图形设备接口GDI进行输出所需要的信息,包括颜色,填充方式,画笔宽度等。在Windows中,DC允许应用程序使用输出设备,DC在应用程序、设备驱动程序、与输出设备之间建立联系,并提供绘图信息。,在MFC中,CDC类封装了设备描述表DC,该类的核心是m_hDC,代表一个指向窗口DC的句柄。,1.CDC类及其派生类,CDC类派生自CObject,它具有CObject类的共同特性,如可以动态创建,可进行序列化操作。,(a).设置颜色,windows使用一个32位无符号整型值来表示图形和文本的颜色,其数据类型为COLORREF,它包含4个字节,第一字节未使用,不要改变其值;后面三个字节分别表示红、绿、蓝三种基本色的成分,每一种颜色用一个0-255之间的数字表示。,设备描述表最常见的使用是在视图类的OnDraw函数中进行图形和文本输出,2.CDC类的使用,宏RGB定义颜色值,宏RGB定义一个颜色的三种基本色成分,返回COLORREF值GetRValue返回一个COLORREF中红色分量GetGValue返回一个COLORREF中绿色分量GetBValue返回一个COLORREF中蓝色分量例:COLORREFcolor=RGB(125,125,125);CBrushbrush(color);TRACE(“TheRedcomponentofthebrushis%dn”,GetRValue(color);,CDC的像素操作函数SetPixel()和GetPixel(),使图形设置精确到像素,(b).像素操作,voidCExView:OnDraw(CDC*pDC)pDC-SetPixel(CPoint(100,100),RGB(255,0,0);,typedefstructtagPOINTLONGx;LONGy;POINT;CPoint是MFC中表示点的类,派生自POINT结构,封装了对CPoint和POINT进行操作的函数,主要是一些运算符函数。,(c).绘制直线及其它图形,CDC用于图形操作的成员函数,MoveTo从当前点移至参数点LineTo从当前点画直线至参数点Polyline用CPoint对象的数组作参数,将数组中各点依次连直线,Rectangle画长方形Ellipse以长方形为界,画一个椭圆Polygon以数组中点为顶点,画一个多边形,(d).文本输出,文本输出包含两部分工作,分别用两组函数实现。设置文本特性如字体,颜色,对齐方式等输出文本,3.使用GDI对象,GDI对象类CGdiObject派生CObject,是画笔、画刷、字体、位图等GDI对象的基类,其派生类封装了各种绘图工具。,a)GDI对象的构造,调用GDI类的构造函数产生一个GDI对象CPenpen1(PS_SOLID,0,RGB(0,255,0);或:CPenpen1;pen1.CreatePen(PS_SOLID,0,RGB(255,0,0);,b)CDC与GDI对象,应用程序本身不需要构造GDI对象,程序中构造一个CDC对象后,系统为其提供了默认的属性和默认的GDI对象,但CDC封装了对GDI操作的成员函数,可以修改相关属性,如SetTextColor();也可选择自定义的GDI对象。,Windows预定义了标准GDI对象,供系统和程序使用,称为备用GDI对象,可为多个程序同时使用。备用对象包括最常用的字体、画笔、画刷等,用函数CDC:SelectStockObject选择备用对象,并返回原值。CPenpen1;/自定义画笔pen1.CreatePen(PS_SOLID,0,RGB(255,0,0);CPen*poldPen=pDC-SelectObject(/恢复原值,表3.15备用GDI对象,c)画笔CPen使用,画笔有线型、线宽、颜色三种属性,在构造画笔时需提供它们的信息。,线型有七种,分别为:实线PS_SOLID点线PS_DOT虚线PS_DASH点画线PS_DASHDOT双点画线PS_DASHDOTDOT空画笔PS_NULL画图形内框PS_INSIDEFRAME,d)画刷CBrush使用,画刷用于填充区域,有三类画刷。根据画刷类型不同,CBrush有多个构造函数。,e)区域使用,CRgn类封装了窗口的GDI区域,该区域可以是由一个或多个椭圆形或多边形合成的,通常将CRgn的成员函数与CDC的剪切成员函数结合使用,实现多种图形显示方式。,面向对象技术有一个术语永久保存(Persistence),即保存应用程序的各种信息。MFC支持两种永久保存:序列化和应用程序状态保存。序列化(Serialization)是指程序的数据保存到文件或从文件读出。应用程序框架提供了完成序列化的大多数结构,程序开发人员只需要完成针对特定应用的数据序列化代码。应用程序运行状态保存通过注册表完成。,3.7.文档的保存,3.7.1.文档序列化,1.序列化,序列化是将数据从应用程序写入数据文件或从数据文件读入应用程序的过程。序列化在文档/视图结构中完成,当用户要保存或读出数据时发生序列化过程,当文档数据发生变化时,序列化会提示用户保存数据。序列化过程从文档类对象序列化开始,文档类可直接序列化普通数据,或序列化对象成员。成员对象各自的类完成自身数据序列化操作。,(3)CArchive为序列化提供一个上下文。,(1)CObject类是所有可序列化类的基类,它提供了序列化的协议和功能,只有派生自CObject的类才能序列化。,(2)CDocument类存储应用程序的数据(数据成员和对象成员),MFC中与序列化相关的类,(4)CFile代表存储在磁盘介质上的文件,直接支持非缓冲文件和二进制文件读写,其派生类支持文本文件和内存文件。,读写过程如下图:,Serialize,2.运行时类型信息,从文件读入对象时,程序根据运行时类型信息(Run-timeclassinformation即RTTI)来判断要读入的对象类型,从而动态地构造(重构)恰当的对象。,每创建一个新的对象,都记录必要的类型信息,产生一个类型信息结构,构成运行时类型信息表(链表),以便运行时进行类型检查。类型信息由CRuntimeClass结构记录。,structCRuntimeClassLPCSTRm_lpszClassName;/类名intm_nObjectSize;UINTm_wSchema;/版本号CObject*(PASCAL*m_pfnCreateObject)();/函数指针,指向该类的缺省构造函数CRuntimeClass*m_pBaseClass;/指向基类的运行时信息结构staticCRuntimeClass*pFirstClass;/链表头指针,静态成员,只有一个CRuntimeClass*m_pNextClass;/指向链表下一对象;,CRuntimeClass,作为可序列化类的公共基类,CObject定义中包含下面的代码:classCObjectpublic:virtualCRuntimeClass*GetRuntimeClass()const;/返回当前类的运行时信息结构指针staticCRuntimeClassclassObject;/静态数据成员,新创建类的信息存储在此;CRuntimeClass*CObject:GetRuntimeClass()constreturn/初始化存放运行时信息的链表为空,说明:CObject派生类在构造对象时,类型信息被记录在其classobject结构成员中,程序中构造的全部对象通过结构体的m_pNextClass指针构成一个类型信息表链表相互关联。将程序(文档)数据保存至文件时,运行时类型信息也被写入文件;从文件读入对象时,程序根据运行时类型信息表中的记录判断要读入的对象类型,调用其缺省构造函数,动态地重构对象。,3.与序列化相关的命令,4.文档类的序列化,如果创建的应用程序不使用数据库,AppWizard为文档类自动生成Serialize函数的框架,由开发人员完成具体的序列化代码。,voidCMyDoc:Serialize(CArchive,5.创建一个可序列化类,d)在类的定义文件(cpp文件)中,添加IMPLEMENT_SERIAL宏,它需要三个参数,分别是需要序列化的类名,其基类名及版本号;,e)重定义Serialize函数,其参数是一个CArchive对象的引用。,c)在类的声明中,添加DECLARE_SERIAL宏,以类名为唯一参数;,只有派生自CObject且重载了Serialize函数的类才能实现序列化,MFC定义了两个宏支持序列化,它们是DECLARE_SERIAL和IMPLEMENT_SERIAL,6.类的序列化,当数据为文档类的对象成员时/Ex3_1Doc.hclassCEx3_1Doc:publicCDocumentCStudentm_Student;/对象成员;/Ex3_1Doc.cppvoidCEx3_1Doc:Serialize(CArchive/调用对象的序列化函数,有了可序列化类,就可作为文档的数据参与序列化.,若数据是指向对象的指针,参看下例。,classCEx3_1Doc:publicCDocumentCStudent*m_pStudent;CEx3_1Doc:CEx3_1Doc():m_pStudent(0)/对象指针初始化为0voidCEx3_1Doc:Serialize(CArchive当然还要修改文档类的OnNewDocment和DeleteContents函数。,BOOLCEx3_1Doc:OnNewDocument()if(!CDocument:OnNewDocument()returnFALSE;m_pStudent=newCStudent;/构造对象returnTRUE;voidCEx3_1Doc:DeleteContents()deletem_pStudent;/删除对象m_pStudent=0;CDocument:DeleteContents();,调用基类的同名函数完成其它功能,返回,注,7.文件对话框中文件类型确定,在Word字处理软件中,打开文件对话框,会显示缺省的文件类型.doc。使用MFC开发的应用程序,可以确定其缺省文件类型,通过编辑字符串资源实现。,在WorkSpace中选择ResourceView,打开StringTable资源,选择ID为IDR_MAINFRAME的字符串,双击它,打开StringProperties对话框,在Caption编辑框中显示下列信息:Ex3_1nnEx3_1nnnEx31.DocumentnEx3_1Document每个字符串由n分隔,n后无字符表示字符串为空。七个字符串的含义,七个字符串含义顺序如下:Ex3_1应用程序主窗口标题栏显示内容,仅SDI需要nNULL文档名,作为新建文档的缺省名,如Ex3_11,后一个1为产生的序列号。此串为空,使新文档窗口标题栏显示”无标题”nEx3_1只与MDI有关,有多个文档模板时的文档模板名nNULL显示在文件对话框文件类型列表框中的信息如”学生信息文件(*.stu)”nNULL缺省的文件后缀,如“*.stu”,上两项现在未定义nEx31.Document注册表中使用的文件类型子项名nEx3_1Document注册表中使用的文件类型名其中第四、五个字符串与文件类型有关。例Ex3_1中对字符串资源修改为行尾的字符串后,打开文件对话框会自动显示文件类型*.stu。,返回,3.7.2.注册表,1.注册表数据库的组织,注册表数据库是一个有关配置信息的层状数据库,层状结构的根部是预定义的原始项(PredefinedKey),提供注册表的入口(Entry),这些原始项包含项(Key)和子项(Subkeys),子项还可包含子项或值(Value)。,程序的运行状态永久保存在注册表中。(这部分内容作为自学,不作为课堂内容。),2.注册表编辑器,注册表编辑器提供一个查看和编辑注册表的可视化界面。运行RegEdit.exe,打开注册表编辑器。警告:错误地编辑注册表可能会严重损坏系统,备份数据.,3.注册表入口文件,注册表入口文件
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 移动端健康医疗应用开发
- 职教数学复习 第7章简单几何体与立体几何 第34讲简单几何体的三视图 课件
- 甲状腺次全切除术课件
- 天津市河东区2024-2025学年高二下学期7月期末物理试题(含答案)
- 用电安全知识培训课件开场白
- 新解读《GB-T 36041-2018压水堆核电厂安全重要变量监测准则》
- 生药学课件-大黄
- 2024垃圾清理协议合同
- 2024建设用地使用权出租合同(8篇)
- 2025年考研英语(一)阅读理解模拟试卷 真题解析与训练
- 办公室文秘岗试题带答案
- 2025年河南疾控中心考试题库
- 2025-2026学年人教精通版四年级英语上册(全册)教学设计(附目录)
- 2025年【高压电工】模拟试题及答案
- 养老护理员竞赛理论试卷答案(含答案)
- 2025年四川省能源投资集团有限责任公司人员招聘笔试备考题库及答案详解(新)
- 广东省公路服务区管理系统升级及运维项目
- 造林后续管理办法
- 市政施工安全培训课件
- 培训完总结做个课件
- 幼儿园6S管理培训
评论
0/150
提交评论