C--面向对象程序设计第12章-利用MFC开发Windows应用程序课件.ppt
C+面向对象程序设计第十二章 利用MFC开发Windows应用程序学习目标(1 1)理解)理解Windows Windows编程思想,理解 编程思想,理解MFC MFC库及其结构 库及其结构(2 2)掌握利用)掌握利用MFC Appwizard MFC Appwizard创建 创建Windows Windows应用程序的步 应用程序的步骤和方法,弄清 骤和方法,弄清MFC Appwizard MFC Appwizard所创建的应用程序中所产 所创建的应用程序中所产生的主要类及其功能、组成文件和程序的框架结构 生的主要类及其功能、组成文件和程序的框架结构(3 3)理解消息映射、消息处理函数的概念。掌握利用)理解消息映射、消息处理函数的概念。掌握利用Class Class Wizard Wizard增加、修改和删除窗口消息处理函数的方法和步骤,增加、修改和删除窗口消息处理函数的方法和步骤,并理解程序代码的变化过程和特点 并理解程序代码的变化过程和特点(4 4)掌握文档)掌握文档/视图结构应用程序的开发过程 视图结构应用程序的开发过程(5 5)掌握菜单、工具栏、控件的使用)掌握菜单、工具栏、控件的使用(6 6)掌握对话框应用程序的开发过程以及数据库访问操作)掌握对话框应用程序的开发过程以及数据库访问操作Windows应用程序的特点与消息驱动机制 n n 基于 基于Windows Windows操作系统的应用程序的特点 操作系统的应用程序的特点 n n 标准的图形用户界面,比如窗口、菜单、按钮、列表 标准的图形用户界面,比如窗口、菜单、按钮、列表框等。框等。n n 应用程序与硬件无关的特性,对于同一类硬件,不论 应用程序与硬件无关的特性,对于同一类硬件,不论哪个厂家或哪个型号,程序都无需进行任何修改就可 哪个厂家或哪个型号,程序都无需进行任何修改就可以运行。以运行。n n 所有的 所有的Windows Windows应用程序都是消息驱动机制,也就是说 应用程序都是消息驱动机制,也就是说Windows Windows程序是通过操作系统发送的消息来处理用户的 程序是通过操作系统发送的消息来处理用户的输入。输入。n n 消息驱动 消息驱动是 是Windows Windows操作系统的一大特色,操作系统将包 操作系统的一大特色,操作系统将包括用户输入在内的各种事件,以消息的形式发送到目标,括用户输入在内的各种事件,以消息的形式发送到目标,目标系统再根据消息的具体内容进行相应的处理。目标系统再根据消息的具体内容进行相应的处理。典型的Windows应用程序结构 n n 控制台应用程序 控制台应用程序:在本书第:在本书第1 1章 章 第 第7 7章介绍的所有程序均 章介绍的所有程序均为控制台应用程序。控制台应用程序结构简单,可以不使 为控制台应用程序。控制台应用程序结构简单,可以不使用 用MFC MFC类库。类库。n n 基于框架窗口的应用程序 基于框架窗口的应用程序:某些应用程序仅需要最小的用:某些应用程序仅需要最小的用户界面和简单的窗口结构,这时可以使用基于框架窗口的 户界面和简单的窗口结构,这时可以使用基于框架窗口的方案。方案。n n 基于文档 基于文档/视图结构的应用程序 视图结构的应用程序:文档:文档/视图应用具有较复 视图应用具有较复杂的结构,当然其功能也相应增强。又可分为单文档 杂的结构,当然其功能也相应增强。又可分为单文档(SDI SDI)和多文档界面()和多文档界面(MDI MDI)两种模式。)两种模式。n n 基于对话框的应用程序 基于对话框的应用程序。学习MFC的方法 n n 不要一开始学习 不要一开始学习Visual C+Visual C+就试图了解整个 就试图了解整个MFC MFC类库。一 类库。一般的学习方法是,先大体上对 般的学习方法是,先大体上对MFC MFC有个了解,知道它的概 有个了解,知道它的概念、组成等之后,念、组成等之后,从较简单的类入手,由浅入深,循序渐 从较简单的类入手,由浅入深,循序渐进、日积月累地学习 进、日积月累地学习。一开始使用。一开始使用MFC MFC提供的类时,只需 提供的类时,只需要知道它的一些常用的方法、外部接口,不必要去了解它 要知道它的一些常用的方法、外部接口,不必要去了解它的细节和内部实现。在学到一定程度时,再深入研究,采 的细节和内部实现。在学到一定程度时,再深入研究,采用继承的方法对原有的类进行修改和扩充,派生出自己所 用继承的方法对原有的类进行修改和扩充,派生出自己所需的类。需的类。利用MFC AppWizard创建Windows应用程序 n n 利用MFC AppWizard 创建一个Windows 应用程序的步骤 n n 第 第1 1步:启动 步:启动Visual C+6.0 Visual C+6.0,选择【,选择【File File】菜单下的【】菜单下的【New New】菜单项,选择【】菜单项,选择【Projects Projects】标签,选择】标签,选择MFC MFC AppWizard(exe)AppWizard(exe)项目类型,在 项目类型,在Project name Project name中输入项目名 中输入项目名MyExp MyExp,定位于,定位于“C:EXAMPLE”“C:EXAMPLE”文件夹中,单击【文件夹中,单击【OK OK】按钮。按钮。n n 第 第2 2步:选择【步:选择【Single document Single document】应用类型,即单文档应】应用类型,即单文档应用程序,其他使用默认值,单击【用程序,其他使用默认值,单击【Next Next】按钮。】按钮。n n 第 第3 3步:让用户选择程序中是否加入数据库支持,在此使 步:让用户选择程序中是否加入数据库支持,在此使用默认值【用默认值【None None】,单击【】,单击【Next Next】按钮。】按钮。n n 第 第4 4步:让用户选择在程序中加入复合文档,自动化支持 步:让用户选择在程序中加入复合文档,自动化支持或 或ActiveX ActiveX控件的支持,在此使用默认值,单击【控件的支持,在此使用默认值,单击【Next Next】按钮。按钮。n n 第 第5 5步:让用户选择应用程序的一些特性,在此使用默认 步:让用户选择应用程序的一些特性,在此使用默认值,单击【值,单击【Next Next】按钮。】按钮。n n 第 第6 6步:让用户选择应用程序主窗口的风格、在源文件中 步:让用户选择应用程序主窗口的风格、在源文件中选择是否加入注释和使用怎样的 选择是否加入注释和使用怎样的MFC MFC类库,在此使用默认 类库,在此使用默认值,单击【值,单击【Next Next】按钮。】按钮。n n 第 第7 7步:用户可以对 步:用户可以对MFC AppWizard MFC AppWizard提供的缺省类名、基 提供的缺省类名、基类名、头文件名、源文件名进行修改,在此使用默认值,类名、头文件名、源文件名进行修改,在此使用默认值,单击【单击【Finish Finish】按钮,显示出用户在前面几个步骤中的选】按钮,显示出用户在前面几个步骤中的选择内容,单击【择内容,单击【OK OK】按钮,系统开始创建应用程序,并】按钮,系统开始创建应用程序,并回到 回到Visual C+6.0 Visual C+6.0的主界面。的主界面。运行过的应用程序 运行过的应用程序MyExp MyExp可以脱离 可以脱离Visual C+6.0 Visual C+6.0单 单独运行,运行该文档可以双击 独运行,运行该文档可以双击“C:EXAMPLEDebug”“C:EXAMPLEDebug”下的 下的MyExp.exe MyExp.exe文件,运行结果如图 文件,运行结果如图12.1 12.1所示。可以看到,和 所示。可以看到,和所有的 所有的Windows Windows应用程序一样,应用程序一样,MyExp MyExp也包含标题栏、菜 也包含标题栏、菜单栏、工具栏、状态栏等窗口元素。单栏、工具栏、状态栏等窗口元素。MFC应用程序的类和文件 n n AppWizard AppWizard在生成应用程序时,共派生了 在生成应用程序时,共派生了5 5个类,单击 个类,单击“MyExp classes”“MyExp classes”左侧的 左侧的“+”“+”展开所有的类,即可显示 展开所有的类,即可显示出应用程序 出应用程序MyExp MyExp的 的5 5个类。其中:个类。其中:n n CAboutDlg CAboutDlg:关于:关于About About对话框的对话框类。对话框的对话框类。n n CMainFrame CMainFrame:主框架窗口类。:主框架窗口类。n n CMyExpApp CMyExpApp:应用程序类。:应用程序类。n n CMyExpDoc CMyExpDoc:文档类。:文档类。n n CMyExpView CMyExpView:视图类。:视图类。n n 在工程中,每个类都拥有自己的类定义文件(在工程中,每个类都拥有自己的类定义文件(*.h*.h)和类)和类实现文件(实现文件(*.cpp*.cpp)。类定义文件主要保存各种类的定义,)。类定义文件主要保存各种类的定义,类实现文件主要保存各种类的成员函数的实现代码 类实现文件主要保存各种类的成员函数的实现代码 AppWiZard 生成的5 个派生类 类定义和类实现文件 文件说明 n n AppWizard AppWizard在自动生成工程时,除了生成上面介绍的各个 在自动生成工程时,除了生成上面介绍的各个类的头文件和实现文件外,还生成了一些为建立应用程序 类的头文件和实现文件外,还生成了一些为建立应用程序所需要的其他文件。这些文件可以在应用程序生成时指定 所需要的其他文件。这些文件可以在应用程序生成时指定的路径(的路径(C:EXAMPLEMyExp C:EXAMPLEMyExp)中找到。)中找到。如下图所示 如下图所示 关于这些文件详细说明 n n 详见教材在窗口的客户区输出文字和图形 SDI SDI中显示字符串 中显示字符串12.2 12.2节中的第 节中的第1 1步到第 步到第7 7步。步。在左边的 在左边的Workspace Workspace下面的 下面的ClassView ClassView中,点击类 中,点击类CMyExpView CMyExpView左边的 左边的+号,双击 号,双击OnDraw()OnDraw(),如图所示。,如图所示。n n 在右边 在右边OnDraw()OnDraw()中加入以下阴影部分的代码,编译、运 中加入以下阴影部分的代码,编译、运行结果如图所示。行结果如图所示。void CMyExpView:OnDraw(CDC*pDC)void CMyExpView:OnDraw(CDC*pDC)CMyExpDoc*pDoc=GetDocument();CMyExpDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);ASSERT_VALID(pDoc);/TODO:add draw code for native data here/TODO:add draw code for native data herepDC-Rectangle(10,10,250,60);pDC-Rectangle(10,10,250,60);/显示一个矩形框 显示一个矩形框pDC-TextOut(20,20,pDC-TextOut(20,20,我的 我的VC+VC+的第一个 的第一个SDI SDI程序。程序。);/);/显示文字 显示文字 程序说明n n 程序对 程序对OnDraw()OnDraw()进行了扩展,使用了 进行了扩展,使用了CDC CDC类的两个成员函 类的两个成员函数:画矩形的 数:画矩形的Rectangle Rectangle()和文字输出()和文字输出TextOut TextOut()。()。n n CDC CDC类中封装了大量的绘图和文字输出方法。类中封装了大量的绘图和文字输出方法。n n 文字信息显示 文字信息显示n n BOOL TextOut(int x,int y,LPCTSTR lpszString);BOOL TextOut(int x,int y,LPCTSTR lpszString);n n 功能:在指定坐标 功能:在指定坐标(x,y)(x,y)处显示字符串 处显示字符串lpszString lpszString的内容,的内容,显示成功返回非 显示成功返回非0 0值,否则返回 值,否则返回0 0。n n 说明:说明:n n 坐标原点 坐标原点(0,0)(0,0)在客户区左上角,在客户区左上角,Y Y轴向下。轴向下。n n LPCTSTR LPCTSTR为常量字符指针类型,为常量字符指针类型,BOOL BOOL为逻辑类型,两 为逻辑类型,两者都是 者都是Windows Windows的数据类型。还有 的数据类型。还有COLORREF COLORREF、POINT POINT、LPPOINT LPPOINT、LPCRECT LPCRECT等都是 等都是Windows API Windows API中 中定义的关键字,通常将它们看作 定义的关键字,通常将它们看作Windows Windows的数据类型。的数据类型。n n 画点 画点n n COLORREF SetPixel(int x,int y,COLORREF color);COLORREF SetPixel(int x,int y,COLORREF color);n n COLORREF SetPixel(POINT point,COLORREF COLORREF SetPixel(POINT point,COLORREF color);color);n n 功能:功能:n n 在指定坐标(用参数 在指定坐标(用参数x,y x,y或点 或点point point给出)处按给定颜色 给出)处按给定颜色(color)(color)画点,返回值为原来此坐标处的颜色。画点,返回值为原来此坐标处的颜色。n n 画线 画线n n 画线工作需经两步完成:画线工作需经两步完成:n n 确定线的起始位置。确定线的起始位置。n n CPoint MoveTo(int x,int y);CPoint MoveTo(int x,int y);n n CPoint MoveTo(POINT point);CPoint MoveTo(POINT point);n n 功能:将绘图位置移至指定坐标处,返回移动前的绘 功能:将绘图位置移至指定坐标处,返回移动前的绘图位置。图位置。n n 确定了线的起点后,使用成员函数 确定了线的起点后,使用成员函数LineTo()LineTo()画线。画线。n n BOOL LintTo(int x,int y);/BOOL LintTo(int x,int y);/参数为终点坐标 参数为终点坐标n n BOOL LintTo(POINT point);BOOL LintTo(POINT point);n n 功能:画线。功能:画线。n n 绘制矩形 绘制矩形n n BOOL Rectangle(int x1,int y1,int x2,int y2);BOOL Rectangle(int x1,int y1,int x2,int y2);n n BOOL Rectangle(LPCRECT lpRect);BOOL Rectangle(LPCRECT lpRect);n n 功能:绘制一个左上角坐标为(功能:绘制一个左上角坐标为(x1,y1 x1,y1),右下角坐标),右下角坐标为(为(x2,y2)x2,y2)的矩形。的矩形。n n 绘制椭圆 绘制椭圆n n BOOL Ellipse(int x1,int y1,int x2,int y2);BOOL Ellipse(int x1,int y1,int x2,int y2);n n BOOL Ellipse(LPCRECT lpRect);BOOL Ellipse(LPCRECT lpRect);n n 功能:绘制一个左上角坐标为(功能:绘制一个左上角坐标为(x1,y1 x1,y1),右下角坐标),右下角坐标为(为(x2,y2)x2,y2)的矩形所围住的椭圆 的矩形所围住的椭圆 Windows消息处理 n n 用户输入响应是 用户输入响应是Windows Windows程序必不可少的功能。例如,当 程序必不可少的功能。例如,当用户在窗口中按下鼠标左键时,用户在窗口中按下鼠标左键时,Windows Windows系统就会发送 系统就会发送WM_LBUTTONDOWN WM_LBUTTONDOWN消息给该窗口,如果程序需要对此消息做 消息给该窗口,如果程序需要对此消息做出反应,必然要调用相应的处理函数,如果没有定义处理 出反应,必然要调用相应的处理函数,如果没有定义处理函数,则该消息被忽略。函数,则该消息被忽略。编制消息处理函数有时又被称作 编制消息处理函数有时又被称作消息映射或捕获消息。消息映射或捕获消息。n n 通过消息映射,消息就和它的处理函数对应起来 通过消息映射,消息就和它的处理函数对应起来 n n 消息处理函数 消息处理函数指的是与某个消息对应的函数。消息处理函 指的是与某个消息对应的函数。消息处理函数的执行是由其对应的消息引发的,某个类对象中的消息 数的执行是由其对应的消息引发的,某个类对象中的消息处理函数是与这个类对象能够得到的一个消息对应的,当 处理函数是与这个类对象能够得到的一个消息对应的,当这个消息发生时,这个函数就会被执行。这个消息发生时,这个函数就会被执行。n n 利用 利用ClassWizard ClassWizard可以管理消息处理函数,可以管理消息处理函数,ClassWizard ClassWizard是 是一个非常强大有用的工具,一个非常强大有用的工具,可以用 可以用ClassWizard ClassWizard来创建新类、来创建新类、定义消息处理函数、覆盖 定义消息处理函数、覆盖MFC MFC的虚拟函数,从对话框、表 的虚拟函数,从对话框、表单视图或记录视图的控件中获取数据。单视图或记录视图的控件中获取数据。n n 可以用 可以用三种方法来激活 三种方法来激活ClassWizard ClassWizard对话框:对话框:n n 选择【选择【View View】菜单中的【】菜单中的【ClassWizard ClassWizard】菜单项;】菜单项;n n 直接按下 直接按下Ctrl+W Ctrl+W键;键;n n 在代码编辑窗口中单击鼠标右键(此时,代码编辑窗 在代码编辑窗口中单击鼠标右键(此时,代码编辑窗口中必须有打开的文件),在弹出菜单中选择【口中必须有打开的文件),在弹出菜单中选择【ClassWizard ClassWizard】菜单项。】菜单项。弹出【MFC ClassWizard】对话框 n n在【在【MFC ClassWizardMFC ClassWizard】对话框上面共有五个选】对话框上面共有五个选项卡,分别说明如下:项卡,分别说明如下:n n【Message Maps Message Maps】选项卡用于进行消息映射的处理;】选项卡用于进行消息映射的处理;n n【Member Variables Member Variables】选项卡用于为对话框中的控件所】选项卡用于为对话框中的控件所用到的类创建成员变量;用到的类创建成员变量;n n【Automation Automation】选项卡帮助用户管理与】选项卡帮助用户管理与OLE OLE自动化相 自动化相联系的方法和属性;联系的方法和属性;n n【ActiveX Events ActiveX Events】选项卡帮助用户管理】选项卡帮助用户管理ActiveX ActiveX类支持 类支持的 的ActiveX ActiveX事件;事件;n n【Class Info Class Info】选项卡显示类的一般信息,包括定义它】选项卡显示类的一般信息,包括定义它的头文件和源文件、类名以及与之相联系的基类。的头文件和源文件、类名以及与之相联系的基类。Windows消息 n n消息就是操作系统通知应用程序某件事情已经发消息就是操作系统通知应用程序某件事情已经发生的一种方式。生的一种方式。例如,当用户移动或双击鼠标、例如,当用户移动或双击鼠标、改变窗口大小等,都将向适当的窗口发送消息,改变窗口大小等,都将向适当的窗口发送消息,一个窗口可以向另一个窗口发送消息。一个窗口可以向另一个窗口发送消息。n nWindowsWindows系统中的消息主要有系统中的消息主要有三种类型三种类型:标准的:标准的WindowsWindows消息、控件消息和命令消息消息、控件消息和命令消息 标准的Windows消息 n n所有以所有以WM_WM_为前缀的消息都是标准的为前缀的消息都是标准的WindowsWindows消消息(息(WM_COMMANDWM_COMMAND消息除外),如消息除外),如WM_PAINTWM_PAINT、WM_QUITWM_QUIT等,这些消息通常含有等,这些消息通常含有用于确定如何对消息进行处理的一些参数。标准用于确定如何对消息进行处理的一些参数。标准的的Windows Windows 消息一般由窗口对象和视图对象进行消息一般由窗口对象和视图对象进行处理处理 n n 标准的 标准的Windows Windows消息可以分为三类,即键盘消息、鼠标消 消息可以分为三类,即键盘消息、鼠标消息和窗口消息 息和窗口消息 n n 鼠标消息 鼠标消息 n n 无论何时移动鼠标或操作鼠标按键,无论何时移动鼠标或操作鼠标按键,Windows Windows便产生一 便产生一条或多条消息并将其发送给位于鼠标光标下的窗口 条或多条消息并将其发送给位于鼠标光标下的窗口 n n 键盘消息 键盘消息 n n 键盘消息的响应函数是 键盘消息的响应函数是OnKeyDown()OnKeyDown(),用于处理,用于处理WM_KEYDOWN WM_KEYDOWN消息(按下键盘上的按键),该函数 消息(按下键盘上的按键),该函数的原型为:的原型为:n n afx_msg OnKeyDown(UINT nChar,UINT nRepCnt,afx_msg OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);UINT nFlags);n n 窗口消息 窗口消息 n n 所有窗口的变化,包括窗口内容重绘 所有窗口的变化,包括窗口内容重绘WM_PAINT WM_PAINT,窗,窗口最大化 口最大化WM_MAXIMIZE WM_MAXIMIZE,窗口最小化,窗口最小化WM_MINIMIZE WM_MINIMIZE,窗口重定义大小,窗口重定义大小WM_RESIZE WM_RESIZE,窗,窗口滚动 口滚动WM_HSCROLL WM_HSCROLL、WM_VSCROLL WM_VSCROLL,窗口定时,窗口定时WM_TIMER WM_TIMER等消息所带参数各不相同 等消息所带参数各不相同 控件消息 n n 控件是一个小的子窗口 控件是一个小的子窗口,属于其他窗口(如对话框等),属于其他窗口(如对话框等),能够接受操作并象父窗口发送消息。常见的控件有按钮、能够接受操作并象父窗口发送消息。常见的控件有按钮、列表框、编辑框、复合框、滚动条等 列表框、编辑框、复合框、滚动条等 n n 发送控件消息的控件在 发送控件消息的控件在Visual C+Visual C+中使用 中使用唯一 唯一ID ID号 号来 来进行 进行标识 标识,使用控件类来操纵,使用控件类来操纵 n n 控件消息分为两类:控件消息分为两类:n n 从控件传给消息,通常这类消息前缀的最后一个字符 从控件传给消息,通常这类消息前缀的最后一个字符为 为N Nn n 由系统发送给控件的消息,这类消息前缀的最后一个 由系统发送给控件的消息,这类消息前缀的最后一个字符为 字符为M M 命令消息 n n 命令消息主要包括由用户界面对象发送的 命令消息主要包括由用户界面对象发送的WM_COMMAND WM_COMMAND消息,用户界面对象是指菜单、工具栏、消息,用户界面对象是指菜单、工具栏、快捷键等 快捷键等。它和控件消息的区别在于:控件消息只能由特。它和控件消息的区别在于:控件消息只能由特定控件向 定控件向Windows Windows系统传送,而命令消息是由用户界面发 系统传送,而命令消息是由用户界面发送的,它可以被更多的对象处理。在文档对象、视图对象、送的,它可以被更多的对象处理。在文档对象、视图对象、窗体对象、控件对象中都能处理这种消息 窗体对象、控件对象中都能处理这种消息 消息的发送与接收的基本过程和机制 n n 在 在Windows Windows中,大部分的消息都是由用户和应用程序的相 中,大部分的消息都是由用户和应用程序的相互作用而产生的 互作用而产生的。CWinApp CWinApp类的成员函数 类的成员函数Run()Run()用于处理 用于处理消息循环,它唯一的功能就是等待消息,并将消息发送到 消息循环,它唯一的功能就是等待消息,并将消息发送到适当的窗口。适当的窗口。n n 当消息循环接收到一条 当消息循环接收到一条Windows Windows消息时,它首先通过查询 消息时,它首先通过查询一种内部结构来确定消息要发送的窗口。这种内部结构把 一种内部结构来确定消息要发送的窗口。这种内部结构把当前所有的窗口映像成其对应的窗口类。当前所有的窗口映像成其对应的窗口类。MFC MFC的基类还能 的基类还能够检测这一目标类是否在其消息中为这一消息提供了处理 够检测这一目标类是否在其消息中为这一消息提供了处理函数入口。如果找到入口,则消息被送往处理函数,结束 函数入口。如果找到入口,则消息被送往处理函数,结束消息发送过程。如果消息无对应入口,则对目标类进行基 消息发送过程。如果消息无对应入口,则对目标类进行基类消息映射检测,沿着层次向上查找,直到找到入口函数 类消息映射检测,沿着层次向上查找,直到找到入口函数为止。为止。文档/视图结构 n n 文档 文档/视图结构大大 视图结构大大简化了多数应用程序的设计开发过程 简化了多数应用程序的设计开发过程,有如下 有如下特点 特点 n n 将对数据的操作与数据显示界面分离,放在不同类的 将对数据的操作与数据显示界面分离,放在不同类的对象中处理。这种思路使得程序模块的划分更加合理。对象中处理。这种思路使得程序模块的划分更加合理。文档对象只负责数据的管理,不涉及用户界面;视图 文档对象只负责数据的管理,不涉及用户界面;视图只负责数据输出和用户的交互,不考虑数据的具体组 只负责数据输出和用户的交互,不考虑数据的具体组织结构细节,并且一个文档类可对应多个视图类。织结构细节,并且一个文档类可对应多个视图类。n n MFC MFC在文档 在文档/视图结构中提供了许多标准的操作界面,视图结构中提供了许多标准的操作界面,如新建、打开、保存、打印等,还支持打印预览、电 如新建、打开、保存、打印等,还支持打印预览、电子邮件发送等功能(可定制),大大减轻了程序员的 子邮件发送等功能(可定制),大大减轻了程序员的工作量。工作量。n n 下面两种情况下不宜采用文档 下面两种情况下不宜采用文档/视图结构:视图结构:n n 不是面向数据的应用程序或数据量很少的应用程序,不是面向数据的应用程序或数据量很少的应用程序,如 如Windows Windows自带的磁盘扫描程序、时钟程序等工具软件,自带的磁盘扫描程序、时钟程序等工具软件,以及一些过程控制程序等。以及一些过程控制程序等。n n 不使用标准窗口界面的程序,如一些游戏软件等。不使用标准窗口界面的程序,如一些游戏软件等。视图类 n n 视图类 视图类CView CView是窗口类 是窗口类CWnd CWnd类的派生类。视图类对象完 类的派生类。视图类对象完全覆盖框架窗口的用户区,没有自己的边框。视图规定了 全覆盖框架窗口的用户区,没有自己的边框。视图规定了用户查看文档数据以及同数据交互的方式 用户查看文档数据以及同数据交互的方式 n n 视图类的几个重要成员函数:视图类的几个重要成员函数:n n GetDocument()GetDocument()成员函数用于从文档类中获取数据值 成员函数用于从文档类中获取数据值 n n OnDraw()OnDraw()成员函数用于更新视图 成员函数用于更新视图 n n OnInitialUpdate()OnInitialUpdate()虚成员函数在应用程序启动,或用户 虚成员函数在应用程序启动,或用户从 从File File菜单中选择了 菜单中选择了New New或者 或者Open Open选项时被调用 选项时被调用 对视图类的处理主要集中在以下4点 n n 处理视图类的 处理视图类的OnDraw()OnDraw()成员函数,该函数负责显示文 成员函数,该函数负责显示文档数据。档数据。n n 将 将Windows Windows消息和用户界面对象(如菜单项等)与视图 消息和用户界面对象(如菜单项等)与视图类中的消息处理函数连接。类中的消息处理函数连接。n n 实现消息处理函数,以便解释用户的输入。实现消息处理函数,以便解释用户的输入。n n 根据需要,在派生的视图类中覆盖 根据需要,在派生的视图类中覆盖CView CView的其他成员函 的其他成员函数 数 n n MFC MFC中提供了各种视图类,这些视图类可以增强应用程序 中提供了各种视图类,这些视图类可以增强应用程序视图的功能 视图的功能 文档类 n n 文档类的几个重要成员函数:文档类的几个重要成员函数:n n OnNewDocument()OnNewDocument()成员函数完成对文档类的数据成员的 成员函数完成对文档类的数据成员的初始化工作 初始化工作 n n DeleteContents()DeleteContents()成员函数完成对文档的清理工作 成员函数完成对文档的清理工作 在使用文档类管理应用程序的数据时,必须做以下在使用文档类管理应用程序的数据时,必须做以下工作:工作:n n 从 从CDocument CDocument类派生出各种不同类型的文档类,每种类型 类派生出各种不同类型的文档类,每种类型对应一种文档。对应一种文档。n n 添加用于存储文档数据的成员变量。添加用于存储文档数据的成员变量。n n 如果需要,可以覆盖 如果需要,可以覆盖CDocument CDocument类的其他成员函数。如覆 类的其他成员函数。如覆盖 盖OnNewDocument()OnNewDocument()以便初始化文档的数据成员,覆盖 以便初始化文档的数据成员,覆盖DeleteContents DeleteContents()()以便销毁动态分配的数据。以便销毁动态分配的数据。n n 在文档类中覆盖 在文档类中覆盖CDocument CDocument类的成员函数 类的成员函数Serialize()Serialize()。成。成员函数 员函数Serialize()Serialize()用于从磁盘读文档数据或把文档数据存入 用于从磁盘读文档数据或把文档数据存入磁盘中。磁盘中。例:在视图中显示鼠标单击位置 n n 第 第1 1步:建立 步:建立SDI SDI项目(项目(My My),见),见12.2 12.2节中的第 节中的第1 1步到第 步到第7 7步。步。n n 第 第2 2步:修改文档类的定义,加入一个 步:修改文档类的定义,加入一个CPoint CPoint类型的变量 类型的变量(代码中的阴影部分),记录鼠标当前单击位置。(代码中的阴影部分),记录鼠标当前单击位置。n n 第 第3 3步:修改视图类的 步:修改视图类的OnDraw()OnDraw()函数,加入显示位置代码 函数,加入显示位置代码 n n 第 第4 4步:用 步:用ClassWizard ClassWizard建立鼠标左键按下的消息处理的函 建立鼠标左键按下的消息处理的函数 数OnLButtonDown(),OnLButtonDown(),并加入以下阴影部分的代码。并加入以下阴影部分的代码。n n 第 第5 5步:编译、运行。程序开始运行时,在窗口中显示出 步:编译、运行。程序开始运行时,在窗口中显示出两个很大的数,用鼠标左键单击窗口客户区任意位置,窗 两个很大的数,用鼠标左键单击窗口客户区任意位置,窗口内显示出当前单击位置的两个坐标值。口内显示出当前单击位置的两个坐标值。例用键盘移动窗口客户区中的一个气球(椭圆)例用键盘移动窗口客户区中的一个气球(椭圆)n n 第 第1 1步:建立 步:建立SDI SDI项目(项目(Mm Mm),见),见8.2 8.2节中的第 节中的第1 1步到第 步到第7 7步。步。n n 第 第2 2步:修改文档类的定义,加入一个 步:修改文档类的定义,加入一个CRect CRect类型的变量记 类型的变量记录椭圆的位置(以下阴影部分)。录椭圆的位置(以下阴影部分)。n n 第 第3 3步:修改文档类的 步:修改文档类的OnNewDocument()OnNewDocument()函数,增加以下 函数,增加以下阴影部分的代码,对 阴影部分的代码,对 m_rectBody m_rectBody进行初始化。进行初始化。n n 第 第4 4步:修改视图类的 步:修改视图类的OnDraw()OnDraw()函数,加入以下阴影部分 函数,加入以下阴影部分的代码。的代码。n n 第 第5 5步:用 步:用ClassWizard ClassWizard 建立键盘的消息处理函数 建立键盘的消息处理函数OnKeyDown OnKeyDown()(),并加入以下阴影部分的代码。,并加入以下阴影部分的代码。菜单、工具栏 n n 菜单是 菜单是Windows Windows应用程序窗口的一个重要组成部分。在 应用程序窗口的一个重要组成部分。在MFC MFC中菜单可以用于 中菜单可以用于SDI SDI(单文档界面)或(单文档界面)或MDI MDI(多文档(多文档界面),以及基于对话框的应用程序。在基于对话框的应 界面),以及基于对话框的应用程序。在基于对话框的应用程序中新建、设计并编辑菜单后,在该对话框的 用程序中新建、设计并编辑菜单后,在该对话框的“属性 属性”选项卡中,将 选项卡中,将Menu Menu属性设置为该菜单的 属性设置为该菜单的ID ID即可。即可。添加/删除菜单项 n n 第 第1 1步:建立 步:建立SDI SDI项目(项目(TestMenu TestMenu),见),见12.2 12.2节中的第 节中的第1 1步 步到第 到第7 7步。步。n n 第 第2 2步:在工程工作区中单击资源视图标签 步:在工程工作区中单击资源视图标签ResourceView ResourceView,切换到资源视图。,切换到资源视图。n n 第 第3 3步:点击 步:点击Menu Menu左边的 左边的+号,展开 号,展开Menu Menu,可以看到,可以看到IDR_MAINFRAME IDR_MAINFRAME,双击之,在右边显示出,双击之,在右边显示出IDR_MAINFRAME IDR_MAINFRAME标志的菜单资源 标志的菜单资源 n n 第 第4 4步:添加菜单项。在要添加的位置上(如 步:添加菜单项。在要添加的位置上(如“帮助 帮助”右 右边)击右键,选 边)击右键,选“Properties”“Properties”,在,在“Caption”“Caption”编辑框 编辑框中输入 中输入“测试菜单 测试菜单(&C)”(&C)”,则在菜单栏中出现,则在菜单栏中出现“测试菜单 测试菜单