




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第3章MFC基本应用程序的建立——Windows编程基础01C++的Windows编程C++的Windows编程自从图形用户界面(GraphicalUserInterface,GUI)的Windows操作系统取代早期的文本模式的DOS系统以后,越来越多的程序员已转而致力于Windows应用程序的研究与开发。早期的Windows应用程序开发是使用C/C++通过调用WindowsAPI所提供的结构和函数来进行的。对于有些特殊的功能,有时还要借助相应的软件开发工具(SoftwareDevelopmentKit,SDK)来实现。这种编程方式由于其运行效率高,因而至今在某些特殊场合中仍旧使用,但它编程繁琐、手工代码量也比较大。下面来看一个简单的Windows应用程序。【例Ex_HelloMsg】一个简单的Windows应用程序#include<windows.h>intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow){ MessageBox(NULL,"你好,我的VisualC++世界!","问候",0); return0;}C++的Windows编程在VisualC++中运行上述程序需要进行以下步骤:①选择“文件”→“新建”→“项目...”菜单命令或按快捷键【Ctrl+Shift+N】或单击标准工具栏中的按钮,弹出“新建项目”对话框,在“项目类型”栏中选中“VisualC++”下的“Win32”,在“模板”栏中选中
;单击按钮,将项目位置定位到“D:\VisualC++程序\第3章”文件夹中,在“名称”栏中输入项目名称“Ex_Start”(双引号不输入)。特别地,要去除“创建解决方案的目录”选项,如图3.1所示。C++的Windows编程②单击按钮,弹出“Win32应用程序向导”对话框,单击按钮,进入“应用程序设置”页面,一定要选中“附加选项”的“空项目”,保留其他默认选项(“Windows应用程序”类型),单击按钮,系统开始创建Ex_Start空项目。③选择“项目”→“添加新项...”菜单命令或按快捷键【Ctrl+Shift+A】或单击标准工具栏中的按钮,弹出“添加新项”对话框,在“类别”栏中选中“VisualC++”下的“代码”,在“模板”栏中选中
;在“名称”栏中输入文件名称“Ex_HelloMsg”(双引号不输入,扩展名.cpp可省略)。C++的Windows编程④单击按钮,在打开的文档窗口中输入上面的代码,按快捷键【F7】编译,出现编译错误“”。为此,应选择“项目”→“Ex_Start属性”菜单命令,在弹出的“Ex_Start属性页”窗口中,将“常规”配置属性中的“字符集”默认值改选为“使用多字节字符集”,如图3.2所示。⑥单击按钮,按快捷键【Ctrl+F5】运行程序,结果如图3.3所示。
C++的Windows编程从上面的程序代码可以看出:(1)C++控制台应用程序以main函数作为进入程序的初始入口点,但在Windows应用程序中,main主函数被WinMain函数取代。WinMain函数的原型如下:intWINAPIWinMain(
HINSTANCE
hInstance, //当前实例句柄
HINSTANCE
hPrevInstance, //前一实例句柄
LPSTR
lpCmdLine, //指向命令行参数的指针 intnCmdShow) //窗口的显示状态(2)每一个C++Windows应用程序都需要Windows.h头文件,它还包含了其他一些Windows头文件。这些头文件定义了Windows的所有数据类型、函数调用、数据结构和符号常量等。(3)程序中结果的输出已不再是显示在屏幕(控制台窗口)上,而是通过对话框(如MessageBox)或窗口来显示或将结果绘制在用户界面元素上。(4)MessageBox是一个Win32API函数,用来弹出一个消息对话框(以后还会讨论)。该函数第1个参数用来指定父窗口句柄,即对话框所在的窗口句柄。第2、3个参数分别用来指定显示的消息内容和对话框窗口的标题,最后一个参数用来指定在对话框中显示的按钮。C++的Windows编程下面再看一个比较完整的Windows应用程序Ex_HelloWin。【例Ex_HelloWin】一个完整的Windows应用程序将项目Ex_Start中的Ex_HelloMsg.cpp排除,添加新项Ex_HelloWin.cpp,输入上述代码。程序编译运行后,单击鼠标左键,就会弹出一个对话框,结果如图3.4所示。C++的Windows编程与【例Ex_HelloMsg】相比,尽管【例Ex_HelloWin】要复杂得多,但总可以将其分解成是两个基本函数的程序结构。一个是WinMain函数,另一个是用户定义的窗口过程函数WndProc。窗口过程函数WndProc用来接收和处理各种不同的消息,而主函数WinMain通常要完成以下几步工作:①调用API函数RegisterClass注册应用程序的窗口类。②调用相关API函数创建和显示窗口,并进行其他必要的初始化处理。其中,函数CreateWindow用来创建已注册窗口类的窗口。Windows每一个窗口都有一些基本属性,如窗口标题、窗口位置和大小、应用程序图标、鼠标指针、菜单和背景颜色等。窗口类就是充当这些属性的模板(容器)。③创建和启动应用程序的消息循环。Windows应用程序接收各种不同的消息,包括键盘消息、鼠标以及窗口产生的各种消息。Windows系统首先将消息放入消息队列中,应用程序的消息循环就从应用程序的消息队列中检取消息,并将消息发送至相应的窗口过程函数中做进一步处理。API函数GetMessage和DispatchMessage就是起到这样的作用。④如果接收到WM_QUIT消息,则调用PostQuitMessage,向系统请求退出。02Windows编程特点1.消息驱动机制2.图形设备接口3.基于资源的程序设计4.动态链接库Windows编程特点1.消息驱动机制前面已经看到,Windows应用程序和C++控制台应用程序之间的一个最根本区别,就在于C++控制台应用程序是通过调用系统函数来获得用户输入的,而Windows应用程序则是通过系统发送的消息来处理用户输入的。例如,对鼠标消息WM_LBUTTONDOWN的处理。在Windows操作环境中,无论是系统产生的动作或是用户运行应用程序产生的动作,都称为事件(Events)产生的消息(Message)。例如,在Windows桌面(传统风格)上,双击应用程序的快捷图标,系统就会根据这个事件产生的消息来执行该应用程序。在Windows的应用程序中,也是通过接收消息、分发消息、处理消息来和用户进行交互的。这种消息驱动的机制是Windows编程的最大特点。Windows编程特点2.图形设备接口在传统的DOS环境中,想要在屏幕或打印机上显示或打印一幅图形是一件非常复杂的事件,因为用户必须按照屏幕分辨率模式以及专用绘图函数在屏幕上绘图,或根据打印机类型及指令规则向打印机输送数据。而Windows则提供了一个抽象的接口,称为图形设备接口(GraphicalDeviceInterface,GDI),使得用户直接利用系统的GDI函数就能方便地实现图形和文本的输出,而不必关心与系统相连的外部设备的类型。3.基于资源的程序设计Windows应用程序常常包含众多图形元素,例如光标、菜单、工具栏、位图、对话框等。实际上,在Windows环境下,每一个这样的元素都作为一种可以装入应用程序的资源来存放。这些资源不仅可以被其他应用程序所共享,而且可以被编辑。需要说明的是,VisualC++为这些资源提供了相应的“所见即所得”编辑器。一般来说,“VisualC++”中的“Visual(可视化)”也正是体现在这点上。Windows编程特点4.动态链接库动态链接库(DynamicLinkLibrary,DLL)提供了一些特定结构的函数,能被应用程序在运行过程中装入和连接,且多个程序可以共享同一个动态链接库,这样就可以大大节省内存和磁盘空间。从编程角度来说,动态链接库可以提高程序模块的灵活性,因为它本身是可以单独设计、编译和调试的。Windows提供了应用程序可利用的丰富的函数调用,大多数用于实现其用户界面与在显示器上显示的文本和图形,都是通过动态链接库来实现的。这些动态链接库是一些具有.DLL扩展名或者是.EXE扩展名的文件。03Windows基本数据类型Windows基本数据类型在前面的示例和函数原型中,有一些“奇怪”的数据类型,如前面的HINSTANCE和LPSTR等,事实上,很多这样的数据类型只是一些基本数据类型的别名,表3.1列出了一些在Windows编程中常用的基本数据类型。Windows所用的数据类型对应的基本数据类型说
明BOOLbool布尔值BSTRunsignedshort*32位字符指针BYTEunsignedchar8位无符号整数COLORREFunsignedlong用作颜色值的32位值DWORDunsignedlong32位无符号整数,段地址和相关的偏移地址LONGlong32位带符号整数LPARAMlong作为参数传递给窗口过程或回调函数的32位值LPCSTRconstchar*指向字符串常量的32位指针LPSTRchar*指向字符串的32位指针LPVOIDvoid*指向未定义类型的32位指针LRESULTlong来自窗口过程或回调函数的32位返回值UINTunsignedint32位无符号整数WORDunsignedshort16位无符号整数WPARAMunsignedint当作参数传递给窗口过程或回调函数的32位值Windows基本数据类型表3.2列出了常用的预定义句柄,它们的类型均为void*,即一个32位指针。句柄类型说
明HBITMAP保存位图信息的内存域的句柄HBRUSH画刷句柄HCURSOR鼠标光标句柄HDC设备描述表句柄HFONT字体句柄HICON图标句柄HINSTANCE应用程序的实例句柄HMENU菜单句柄HPALETTE颜色调色板句柄HPEN在设备上画图时用于指明线型的笔的句柄HWND窗口句柄需要说明的是:(1)这些基本数据类型都是以大写字符出现的,以与一般C++基本数据类型相区别。(2)凡是数据类型的前缀是P或LP,则表示该类型是一个指针或长指针数据类型。如果前缀是H,则表示是句柄类型。若前缀是U,则表示是无符号数据类型,等等。(3)Windows还提供一些宏来处理上述基本数据类型。例如,LOBYTE和HIBYTE分别用来获取16位数值中的低位和高位字节;LOWORD和HIWORD分别用来获取32位数值中的低位和高位字;MAKEWORD是将两个16位无符号值结合成一个32位无符号值,等等。第3章MFC基本应用程序的建立——创建MFC应用程序01设计一个MFC程序设计一个MFC程序在理解MFC程序框架机制之前,先来看一个MFC应用程序。【例Ex_HelloMFC】一个MFC应用程序在VisualC++中运行上述MFC程序需要进行以下步骤:①将Ex_HelloWin.cpp从项目Ex_Start中排除,添加新项Ex_HelloMFC.cpp,输入上述代码。②选择“项目”→“Ex_Start属性”菜单命令,弹出“Ex_Start属性页”窗口。在左侧栏中选中“常规”类别,在右侧“配置类型”栏中的“MFC的使用”中,将其配置为“在共享DLL中使用MFC”。单击按钮。③程序编译运行后,单击鼠标左键,就会弹出一个对话框,结果同【例Ex_HelloWin】。02理解程序代码理解程序代码当用户运行应用程序时,Windows会自动调用应用程序框架内部的WinMain函数,并自动查找该应用程序类CHelloApp(从CWinApp派生)的全局变量theApp,然后自动调用CHelloApp的虚函数InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。下面来看看上述程序中InitInstance的执行过程。(1)首先执行的是:m_pMainWnd=newCMainFrame();该语句用来创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成了窗口创建工作。(2)然后执行后面两句:m_pMainWnd->ShowWindow(m_nCmdShow);m_pMainWnd->UpdateWindow();用作窗口的显示和更新。(3)最后返回TRUE,表示窗口创建成功。需要说明的是,全局的应用程序派生类CHelloApp对象theApp在构造时还自动进行基类CWinApp的初始化,这使得在InitInstance完成初始化工作之后,还调用基类CWinApp的成员函数Run,执行应用程序的消息循环,即重复执行接收消息并转发消息的工作。当Run检查到消息队列为空时,将调用基类CWinApp的成员函数OnIdle进行空闲时的后台处理工作。03使用MFC项目向导使用MFC项目向导VisualC++中的MFC项目向导能为用户快速、高效、自动地生成一些常用的标准程序结构和编程风格的应用程序,它们被称为应用程序框架结构。前面的【例Ex_HelloMsg】和【例Ex_HelloWin】事实上正是使用它的Win32项目向导类型。在VisualC++中,选择“文件”→“新建”→“项目”菜单命令或按快捷键【Ctrl+Shift+N】或单击标准工具栏中的按钮,弹出“新建项目”对话框,可以看到在“项目类型”栏中有许多相应的项目类型,如图3.5所示。使用MFC项目向导这些类型能满足各个层次的需要,但更关心的是类型,因为它包含了一般创建的最常用、最基本的三种应用程序类型:单文档、多文档和基于对话框的应用程序。所谓单文档应用程序是类似于Windows记事本的程序,它的功能比较简单,复杂程度适中,虽然每次只能打开和处理一个文档,但已能满足一般工程上的需要。因此,大多数应用程序的编制都是从单文档程序框架开始的。与单文档应用程序相比较,基于对话框的应用程序是最简单,也是最紧凑的。它没有菜单、工具栏及状态栏,也不能处理文档,但它的好处是速度快,代码少,程序员所花费的开发和调试时间短。多文档应用程序,顾名思义,能允许同时打开和处理多个文档。与单文档应用程序相比,增加了许多功能,因而需要大量额外的编程工作。例如它不仅需要跟踪所有打开文档的路径,而且还需要管理各文档窗口的显示和更新等。04创建文档应用程序1.开始2.应用程序类型3.复合文档支持4.文档模板字符串5.数据库支持6.用户界面功能7.高级功能8.生成的类9.编译并运行创建文档应用程序用向导可以方便地创建一个通用的Windows单文档应用程序,其步骤如下。1.开始打开“新建项目”对话框,参看图3.5,在左侧“项目类型”中选中“MFC”,在右侧的“模板”栏中选中
类型(以后所论及的“MFC应用程序向导”就是指这种操作),检查并将项目工作文件夹定位到“D:\VisualC++程序\第3章”,在“名称”栏中输入项目名Ex_SDIHello。2.应用程序类型单击按钮,出现“MFC应用程序向导”欢迎页面,显示项目当前设置的所有属性,单击按钮,出现如图3.6所示的“应用程序类型”页面。创建文档应用程序其中,“应用程序类型”可有下列选择:(1)“单个文档”,即单文档应用程序。(2)“多个文档”,即多文档应用程序。当选中“选项卡式文档”选项时,则打开的多个文档的窗口管理采用“选项卡”标签页面方式,集中布排在同一个窗口区域中。(3)“基于对话框”,即基于对话框的应用程序。当选中“使用HTML对话框”选项时,则对话框使用HTML资源界面,其中的控件与运行满足HTML规范。(4)“多个顶级文档”,它属于多文档应用程序的一种,程序打开窗口的状态和任务管理器中的运行状态与Word2016相似。创建文档应用程序3.复合文档支持保留其他默认选项,单击按钮,出现如图3.7所示的对话框,允许在程序中加入复合文档和活动文档的不同级别的支持。4.文档模板字符串保留默认选项,单击按钮,出现如图3.8所示的对话框,从中可对文档模板字符串中的相关内容进行设置。创建文档应用程序5.数据库支持保留默认选项,单击按钮,出现如图3.9所示的对话框,从这里可选择程序中是否加入数据库的支持(有关数据库的内容将在以后的章节中介绍)。创建文档应用程序6.用户界面功能保留默认选项,单击按钮,出现如图3.10所示的对话框,在这里可对主框架窗口、菜单/工具栏等界面进行设置(以后还会讨论)。选中“使用经典菜单”选项时,将弹出对话框提示将禁用所有新的外观功能(选项卡文档、视觉样式和颜色),询问是否继续,单击按钮。选中“使用传统的停靠工具栏”选项。创建文档应用程序7.高级功能保留其他默认选项,单击按钮,出现如图3.11所示的对话框,在这里可对上下文帮助、打印、自动化、ActiveX及在最近使用文件数等项进行设定。特别地,“高级框架窗格”是对前面“应用程序类型”步骤中的“VisualStudio”和“Office”的“项目类型”界面的一些选项指定。8.生成的类保留默认选项,单击按钮,出现如图3.12所示的对话框,在这里可以对向导创建的默认类名、基类名(以后还会讨论)、各个源文件名进行修改。创建文档应用程序9.编译并运行单击按钮,系统开始创建,并又回到VisualC++主界面。到这里为止,虽然没有编写任何程序代码,但向导已根据前面的选择自动生成相应的应用程序框架。按快捷键【Ctrl+F5】,系统开始编连并运行生成的单文档应用程序可执行文件Ex_SDIHello.exe,结果如图3.13所示。标题栏工具栏文档窗口菜单栏状态栏创建文档应用程序需要说明的是,MicrosoftVisualStudio2008对MFC文档应用程序界面作了全面美化,提供了“视觉管理器和样式”功能,包含了Windows2000、WindowsXP、Office2003、Office2007以及VisualStudio2005等不同的界面风格。例如,用向导创建一个单文档应用程序Ex_T,按下操作:①在向导的“应用程序类型”中选定“单个文档”、“MFC标准”、“VisualStudio2005”或“Office2003”,去除“启用视觉样式切换”选项,如图3.14所示。②在“用户界面功能”页面中,去除“个性化菜单行为”选项,如图3.15所示。保留其他默认选项,单击按钮。
创建文档应用程序③选择“项目”→“Ex_T属性”菜单命令,在弹出的“Ex_T属性页”窗口中,将“常规”配置属性中的“字符集”默认值改选为“使用多字节字符集”,单击按钮。④编译并运行,结果如图3.16所示。第3章MFC基本应用程序的建立——MFC应用程序框架01项目和解决方案项目和解决方案定位到创建时指定的工作文件夹“D:\VisualC++程序\第3章”,可以看到Ex_SDIHello文件夹,打开它可看到单文档应用程序Ex_SDIHello所有的文件和信息。由于应用程序还包含了除源程序文件外的许多信息,因此,在VisualC++中常将其称为项目或工程。一个项目可简单,也可复杂。一个简单的项目可能仅由一个对话框或一个HTML文档、源代码文件和一个项目文件组成。但若是复杂的项目,则还可能在这些项的基础上包括数据库脚本、存储过程和对现有XMLWebServices的引用等内容。随着软件工程不断发展以及.NET技术的推出,VisualStudio采用了“解决方案”来组织项目。解决方案,作为VisualStudio另一类容器,其外延要比“项目”要宽得多。一个解决方案可包含多个项目,而一个项目通常包含多个项。所谓的“项”,就是创建应用程序所需的引用、数据连接、文件夹和文件等。02解决方案管理和配置1.解决方案资源管理器2.类视图3.属性管理器解决方案管理和配置1.解决方案资源管理器工作区窗口的“解决方案资源管理器”页面用来将解决方案中的所有文件(C++源文件、头文件、资源文件、Help文件等)分类,并按树层次结构来显示。每一个类别的文件在该页面中都有自己的节点,例如,所有的.cpp源文件都在“源文件”目录项,而.h文件都在“头文件”目录项中。在该页面中,用户不仅可以在节点项中移动文件,而且还可以创建新的节点项以及将一些特殊类型的文件放在该节点项中。单击节点名称图标前的符号“+”或“-”或双击图标,将显示或隐藏节点下的相关内容。如图3.17(左)所示。
解决方案管理和配置当选定顶部节点(例如
)时,“解决方案资源管理器”窗口的顶部出现三个工具图标
。其中,用来显示树视图中所选项的相应“属性页”对话框;用来显示所有项目项,包括那些已经被排除的项和正常情况下隐藏的项;而用来启动“类设计器”,显示当前项目中类的关系图。需要说明的是,选择的节点项不同,对应的窗口顶部出现的工具图标也不同。同时,右击节点的快捷菜单也各不相同。例如,右击
节点,弹出如图3.17(右)所示的快捷菜单,从中可选择相应的命令和操作。解决方案管理和配置2.类视图单击工作区窗口底部的“类视图”标签,可切换至“类视图”页面,它是用来显示和管理项目中所有的名称空间、类和方法。“类视图”包含上下两栏:“类别和类”、“成员”,如图3.18(左)所示。“类别和类”栏位于整个页面的上部,它以“树”结构来显示当前方案中的“类别”(包括映射、宏和常量、全局函数和变量等)或“类”(以后还会讨论),其顶级节点(根)是当前的项目节点。若要展开树中选定的节点,则应单击节点前的加号按钮或按数字小键盘上的加号(+)键。同样,若要收起选定的已展开节点,则应单击节点前的减号按钮或按数字小键盘上的减号(-)键。“成员”栏位于页面的下部,用列表方式列出当前所选“类别”或“类”节点中的属性、方法、事件、变量、常量及其他成员。双击这些“成员”项,将在文档窗口中自动打开并定位到当前项的定义处。当然,若右击“成员”项,例如右击CEx_SDIHelloView类的
项,则弹出如图3.18(右)所示的快捷菜单,从中可选择相应的命令和操作。
解决方案管理和配置3.属性管理器单击工作区窗口底部的“属性管理器”标签,切换至“属性管理器”页面,如图3.19所示,双击任何节点都将弹出相应的“属性页”对话框,从中可修改属性表中定义的项目设置。默认时,一个VisualC++项目(解决方案)一般总会有Debug(调试)和Release(发行)两种类型的属性表。所谓“调试”版本,它是为调试而配置,所生成的程序中包含了大量调试信息,而“发行”版本是用来生成最终的应用程序,它对所生成的代码进行充分优化,生成的代码更小、速度更快。解决方案管理和配置需要说明的是,这里的项目属性仅是预定义的方案,具体项目生成的版本还需要通过选择“生成”→“配置管理器”菜单命令,在弹出的对话框中进行指定,如图3.20所示。配置时,可通过对话框上方的“活动解决方案配置”的组合框选项来进行,也可在对话框项目配置列表中为某个具体的项目进行配置。由于Ex_SDIHello方案中仅有一个同名的项目,所以这两种操作方式结果是相同的。事实上,项目配置也可直接通过“标准”工具栏进行,如图3.21所示。03MFC程序类结构MFC程序类结构将VisualC++解决方案资源工作区窗口切换到“类视图”页面,属开顶部节点,可以看到MFC为单文档应用程序项目Ex_SDIHello自动创建了类CAboutDlg、CEx_SDIHelloApp、CEx_SDIHelloDoc、CEx_SDIHelloView和CMainFrame。这些MFC类之间的继承和派生关系如图3.22所示。MFC程序类结构其中,对话框类CAboutDlg是每一个应用程序框架都有的,用来显示本程序的有关信息。它是从对话框类CDialog派生的。CEx_SDIHelloApp是应用程序类,它从CWinApp类派生而来,负责应用程序创建、运行和终止,每一个应用程序都需要这样的类。CWinApp类是应用程序的主线程类,它是从CWinThread类派生而来。CWinThread类用来完成对线程的控制,包括线程的创建、运行、终止和挂起等。CEx_SDIHelloDoc是应用程序文档类,它从CDocument类派生而来,负责应用程序文档数据CEx_SDIHelloView是应用程序视图类,它既可以从基类CView派生,也可以从CView派生类(如CListView、CTreeView等)派生,负责数据的显示、绘制和其他用户交互。CMainFrame类用来负责主框架窗口的显示和管理,包括工具栏和状态栏等界面元素的初始化。对于单文档应用程序来说,主框架窗口类是从CFrameWnd派生而来的。CFrameWnd的基类CWnd是一个通用的窗口类,用来提供Windows中的所有通用特性、对话框和控件。CFrameWnd的派生类CMDIFrameWnd和CMDIChildWnd类分别用来进行多文档应用程序的主框架窗口和文档子窗口的显示和管理。CMiniFrameWnd类是一种简化的框架窗口,它没有最大化和最小化窗口按钮,也没有窗口系统菜单,一般很少用到它。CObject类是MFC提供的绝大多数类的基类。该类完成动态空间的分配与回收,支持一般的诊断、出错信息处理和文档序列化等。CCmdTarget类主要负责将系统事件(消息)和窗口事件(消息)发送给响应这些事件的对象,完成消息发送、等待和派遣(调度)等工作,实现应用程序的对象之间协调运行。第3章MFC基本应用程序的建立——消息和消息映射01消息类别消息类别Windows应用程序中的消息主要有下面三种类型。(1)(2)(3)窗口消息(WindowsMessage)。这类消息主要是指由WM_开头的消息,但WM_COMMAND除外,例如WM_CREATE(窗口对象创建时产生)、WM_DESTROY(窗口对象清除前发生)、WM_PAINT(窗口更新时产生绘制消息)等,一般由窗口类和视图类对象来处理。窗口消息往往带有参数,以标志处理消息的方法。控件的通知消息(ControlNotifications)。当控件的状态发生改变(例如,用户在控件中进行输入)时,控件就会向其父窗口发送WM_COMMAND通知消息。应用程序框架处理控件消息的方法和窗口消息相同,但按钮的BN_CLICKED通知消息除外,它的处理方法与命令消息相同。命令消息(CommandMessage)。命令消息主要包括由用户交互对象(菜单、工具条的按钮、快捷键等)发送的WM_COMMAND通知消息。02消息映射和属性窗口1.打开属性窗口2.映射消息消息映射和属性窗口1.打开属性窗口在VisualC++中,打开“属性窗口”可以使用下列几种方法:(1)在解决方案资源工作区窗口中,任意右击某节点,从弹出的快捷菜单中选择“属性”命令。(2)选择“视图”→“其他窗口”→“属性窗口”菜单命令或直接使用【Alt+Enter】快捷键。这样就会在开发环境的右侧,显示出“属性窗口”。“属性窗口”将根据当前节点及上下文情况显示出相应的属性列表。需要说明的是,若在某个类(如CEx_SDIHelloView)中添加映射,则应在工作区窗口“类视图”中单击类节点,这样就可在“属性窗口”中分别依次单击顶部的按钮,就可显示出该类可映射的“事件”、“消息”以及对虚函数的“重写”(重载),如图3.23所示。
消息映射和属性窗口2.映射消息下面以向CEx_SDIHelloView中添加WM_LBUTTOMDOWN(鼠标左击产生的消息)的消息映射为例,说明其消息映射的一般过程:①在解决方案资源工作区窗口“类视图”中,右击类节点,从弹出的快捷菜单中选择“属性”命令,显示“属性窗口”(默认位置在开发环境的右侧)。②在“属性窗口”的顶部单击消息按钮,此时属性列表中显示出可映射的全部消息,拖动右侧的滚动块,直到出现要映射的WM_LBUTTOMDOWN消息为止。③在WM_LBUTTOMDOWN属性项的右侧栏单击鼠标,将出现一个下拉按钮,单击它,结果如图3.24(左)所示,从中选择“”,这样就为CEx_SDIHelloView中添加了鼠标消息WM_LBUTTOMDOWN的映射函数OnLButtonDown。此时“属性窗口”内容改变,文档窗口自动打开并定位到刚添加的消息映射函数OnLButtonDown实现处。消息映射和属性窗口需要说明的是,一个事件可能会产生多种消息,所以“消息映射函数”又可称为“事件处理程序”。④在OnLButtonDown实现处,添加下列代码:voidCEx_SDIHelloView::OnLButtonDown(UINTnFlags,CPointpoint){ //TODO:在此添加消息处理程序代码和/或调用默认值 MessageBox("你好,我的VisualC++世界!","问候",0); CView::OnLButtonDown(nFlags,point);}⑤这样就完成了一个消息映射过程。将“常规”配置属性中的“字符集”默认值改选为“使用多字节字符集”后,编译并运行程序,在窗口客户区单击鼠标左键,就会弹出一个消息对话框。需要说明的是:
由于鼠标和键盘消息都是MFC预定义的窗口命令消息,它们各自都有相应的消息处理宏和预定义消息处理函数,因此消息映射函数名称不再需要用户重新定义。但是,对于菜单和按钮等命令消息(事件)来说,在“属性窗口”映射时,还需指定消息(事件)映射函数的名称(以后还会讨论)。
若指定的消息映射函数需要删除,则在“属性窗口”中选中消息后,单击右侧的下拉按钮,从弹出的下拉项中选择“<删除>...”即可,如图3.24(右)所示。这样,VisualStudio2008就会通过在映射代码行前面加上“行注释”(//)的方式将其“删除”掉。03消息映射代码框架消息映射代码框架查看上述CEx_SDIHelloView程序代码,可以发现:MFC为WM_LBUTTONDOWN的消息映射作了以下三个方面的内容安排:(1)在头文件Ex_SDIHelloView.h中声明消息处理函数OnLButtonDown:protected: DECLARE_MESSAGE_MAP()public: afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);(2)在Ex_SDIHelloView.cpp源文件前面的消息映射入口处,添加了WM_LBUTTONDOWN的消息映射宏ON_WM_LBUTTONDOWN:BEGIN_MESSAGE_MAP(CEx_SDIHelloView,CView) //消息映射开始 //标准打印命令 ON_COMMAND(ID_FILE_PRINT,&CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT,&CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW,&CView::OnFilePrintPreview) ON_WM_LBUTTONDOWN()END_MESSAGE_MAP() //消息映射结束消息映射代码框架(3)在Ex_SDIHelloView.cpp文件中写入一个空的消息函数(处理程序)的模板,以便用户填入具体代码,如下面的框架:voidCEx_SDIHelloView::OnLButtonDown(UINTnFlags,CPointpoint){ //TODO:在此添加消息处理程序代码和/或调用默认值 CView::OnLButtonDown(nFlags,point);}事实上,根据MFC产生的上述消息映射过程,用户可以自己手动添加一些“属性窗口”不支持的消息映射函数,以完成特定的功能。04键盘和鼠标消息键盘和鼠标消息当键按下时,Windows将WM_KEYDOWN或WM_SYSKEYDOWN放入具有输入焦点的应用程序窗口的消息队列中。当键被释放时,Windows则把WM_KEYUP或WM_SYSKEYUP消息放入消息队列中。对于字符键来说,还会在这两个消息之间产生WM_CHAR消息。当前类的“属性窗口”消息页面可方便地添加WM_KEYDOWN和WM_KEYUP击键消息映射函数的调用,它们具有下列函数原型:afx_msgvoidOnKeyDown(UINTnChar,UINT
nRepCnt,UINT
nFlags);afx_msgvoidOnKeyUp(UINT
nChar,UINTnRepCnt,UINTnFlags
);afx_msg是MFC用于定义消息函数的标志,参数nChar表示“虚拟键代码”,nRepCnt表示当用户按住一个键时的重复计数,nFlags表示击键消息标志。所谓虚拟键代码,是指与设备无关的键盘编码。在VisualC++中,最常用的虚拟键代码已被定义在Winuser.h中,例如:VK_SHIFT表示【Shift】键,VK_F1表示功能键【F1】等。同击键消息一样,“属性窗口”消息页面也提供相应的字符消息处理框架,并能方便地添加当前类的WM_CHAR消息映射函数的调用,它具有下列函数原型:afx_msgvoidOnChar(UINT
nChar,UINT
nRepCnt,UINT
nFlags);参数nChar表示键的ASCII码,nRepCnt表示当用户按住一个键时的重复计数,nFlags表示字符消息标志。键盘和鼠标消息由于键盘消息属于窗口消息(以WM_为开头的),故只能被窗口对象加以接收、处理。若将键盘消息映射在CMainFrame、CChildFrame(多文档)、用户应用程序类中,则不管消息映射函数中的用户代码究竟如何,都不会被执行。当用户对鼠标进行操作时,像键盘一样也会产生对应的消息。通常,Windows只将键盘消息发送给具有输入焦点的窗口,但鼠标消息不受这种限制。只要鼠标移过窗口的客户区时,就会向该窗口发送WM_MOUSEMOVE(移动鼠标)消息。这里的客户区是指窗口中用于输出文档的区域。当在窗口的客户区中双击、按下或释放一个鼠标键时,就会根据所操作的鼠标按键(LBUTTON、MBUTTON和RBUTTON)向该窗口发生DBLCLK(双击)、DOWN(按下)和UP(释放)消息,如表3.3所示。鼠
标
键按
下释
放双
击左WM_LBUTTONDOWNWM_LBUTTONUPWM_LBUTTONDBLCLK中WM_MBUTTONDOWNWM_MBUTTONUPWM_MBUTTONDBLCLK右WM_RBUTTONDOWNWM_RBUTTONUPWM_RBUTTONDBLCLK键盘和鼠标消息对于所有鼠标按键消息来说,MFC都会将其映射成类似afx_msgvoidOnXXXX的消息处理函数,如前面WM_LBUTTONDOWN的消息函数OnLButtonDown,它们具有下列函数原型:afx_msgvoidOnXXXX(UINT
nFlags,CPoint
point
);其中,point表示鼠标光标在屏幕的(x,y)坐标;nFlags表示鼠标按钮和键盘组合情况,它可以是下列值的组合(MK前缀表示“鼠标键”):MK_CONTROL ——键盘上的Ctrl键被按下MK_LBUTTON ——鼠标左键被按下MK_MBUTTON ——鼠标中键被按下MK_RBUTTON ——鼠标右键被按下MK_SHIFT ——键盘上的Shift键被按下若要判断某个键是否被按下,则可用对应的标识与nFlags进行逻辑“与”(&)运算,所得结果为true时,表示该键被按下。例如,若收到了WM_LBUTTONDOWN消息,且值nFlags&MK_CONTROL是true时,则表明按下鼠标左键的同时也按下【Ctrl】键。05其他窗口消息其他窗口消息在系统中,除了用户输入产生的消息外,还有许多系统根据应用程序的状态和运行过程产生的消息,有时也需要用户跟踪或进行处理。(1)WM_CREATE消息。它是在窗口对象创建后向视图发送的第一个消息;如果有什么工作需要在初始化时处理,就可在该消息处理函数中加入所需代码。但是,由于WM_CREATE消息发送时,窗口对象还未完成,窗口还不可见,因此在该消息处理函数OnCreate内,不能调用那些依赖于窗口处于完成激活状态的Windows函数,如窗口绘制函数等。(2)WM_CLOSE或WM_DESTROY消息。当用户从系统菜单中关闭窗口或者父窗口被关闭时,Windows都会发送WM_CLOSE消息;而WM_DESTROY消息是在窗口从屏幕消失后发送的,因此它紧随WM_CLOSE之后。(3)WM_PAINT消息。当窗口的大小发生变化、窗口内容发生变化、窗口间的层叠关系发生变化或调用函数UpdateWindow或RedrawWindow时,系统都将产生WM_PAINT消息,表示要重新绘制窗口的内容。该消息处理函数的原型是;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年美容师考试新技术应用及答案
- 宠物营养师的能力建设与职业发展试题及答案
- 2024年宠物营养师的国际交流与合作试题及答案
- 宠物营养影响因素探讨试题及答案
- 第1讲 光电效应 波粒二象性-2026版大一轮高考物理复习
- 美容师考试技能测试重点及试题答案
- 车辆配置对二手车评估的影响分析试题及答案
- 建筑工程管理职称课件
- 找颜色的测试题及答案
- 2024年计算机基础考试模拟试题试题及答案
- 技术标编制培训
- 【小学数学课件】搭积木课件
- 防诈骗知识培训课件内容
- DB32/T 3356-2018 南京椴组培育苗技术规程
- GB/T 44982-2024绿色产品评价日用陶瓷
- 提高施工现场从业人员隐患上报(举报)率 -4:3
- 戏剧常识知识考试试题题库及答案
- 小牛在线2018第四季度营销方案20181106
- 职业院校“金课”建设方案
- 医疗护理员基础理论知识考试试题题库及答案
- JT-T-1051-2016城市轨道交通运营突发事件应急预案编制规范
评论
0/150
提交评论