第1章 Windows应用程序框架的 创建与消息处理
1.1 创建Windows应用程序框架 MFC的类可以处理许多标准的Windows编程任务。用MFC来生成Windows应用程序框架的步骤。 步骤1:启动Visual C++6.0。 “开始”—>“程序”_—>“Microsoft Visual Studio” —>“Microsoft Visual C++ 6.0” ,如下图所示。
步骤2:选择“文件”—>“新建..Ctrl+N”菜单项,系统弹出“新建”对话框,单击“工程”选项卡 —>MFC AppWizard(exe);工程框中输入工程的名称, “C位置:”编辑框中输入保存该工程文件的路径 .如下图所示。
步骤3:MFC AppWizard的第1步将弹出MFC AppWizard-Step 1对话框,如下图所示。在此例中,选择单文档应用程序。
步骤4:在AppWizard的第2步将弹出对话框MFC AppWizard-Step 2 of 6,如下图所示。
步骤5:AppWizard的第3步将弹出MFC AppWizard-Step 3 of 6对话框,如下图所示。在本例中,我们所要创建的应用程序不需要复合文档的支持,因此选中“O不”。
步骤6:AppWizard的第4步将弹出MFC AppWizard-Step 4 of 6对话框,如下图所示。
步骤7:AppWizard的第5步将弹出MFC AppWizard-Step 5 of 6对话框,如下图所示。在本例中,我们接受系统的默认设置 。
步骤8:AppWizard的第6步将弹出MFC AppWizard-Step 6 of 6对话框,如下图所示。
单击“完成”(Finish)按钮,弹出如下图所示的“新建工程信息”对话框,此对话框中显示了所创建的工程的信息。单击“确定”按钮,回到Visual C++6.0的主界面。
步骤9:选择“编译”—>“构件框架. Exe”菜单项,对工程进行编译和链接,生成可执行文件。再选择“编译” —>“执行框架 步骤9:选择“编译”—>“构件框架. Exe”菜单项,对工程进行编译和链接,生成可执行文件。再选择“编译” —>“执行框架. Exe”菜单命令运行程序。
AppWizard工具生成的文件及其用途分析
1.2 应用程序的分析 Visual C++为我们所创建的程序构造了如下的对象: l 应用程序对象:生成的应用程序框架。 1.2 应用程序的分析 Visual C++为我们所创建的程序构造了如下的对象: l 应用程序对象:生成的应用程序框架。 l 文档对象Cdocument:反映文件的内容。 l视图对象Cview:文档和用户之间进行交互的窗口。 l l 主框架对象CmainFrame:限定应用程序窗口范围的对象,其他可显示对象都在此范围内。 l文档模板:生成和管理文档。
程序的执行过程 : 程序的入口函数是WinMain(),接着WinMain()函数调用InitInstance()函数来初始化应用程序。同时在此函数中要构造文档模板,产生最初的文档、视图和主框架窗口,然后生成工具栏和状态栏。 当InitInstance()函数执行完毕后,WinMain()函数将调用成员函数Run(),进入处理消息的循环。这时,应用程序的基本窗口已经生成,应用程序准备接收系统或用户的消息,完成用户需要的功能。 当程序终止时,接收到WM_QUIT消息,MFC调用CWinApp类的成员函数ExitInstance(),然后调用静态对象的析构函数,包括CWinApp对象,最后退出应用程序,将控制权交给操作系统。
1.3 Windows的消息 在Windows中,事件也称为消息,所有的Windows应用程序都是消息驱动的。在一个事件驱动的应用程序中,所有的操作都是对事件的响应。因而,在Windows程序设计中如何处理程序的消息是Windows应用程序的核心。
1.3.1 消息的处理机制 操作系统将包括用户输入在内的各种事件,以消息的形式发送到目标,目标系统再根据消息的具体内容进行相应的处理。一条消息包括4项内容:目标窗口、消息类型、参数1wParam及参数2lParam。 对MFC来说,只有CMainFrame类和CView类及它们的派生类才能接收消息。不同的消息由操作系统或应用程序的不同部分进行处理。例如,当用户在窗口中移动鼠标时,窗口将得到一个WM_MOUSEMOVE消息 。
1.3.2 Windows程序中的消息分类 在Windows程序中,消息大致可以分为3类:标准的Windows消息、控件消息和命令消息。 键盘消息对键盘的某个键的动作相关。 鼠标消息涉及到鼠标的单击、双击、拖动等。 窗口消息一般与创建窗口、绘制窗口、移动窗口和销毁窗口等动作有关。
(1)键盘消息。当键盘的某个键被按下时,将产生WM_CHAR消息, 其消息的处理函数为OnChar(),此函数的原型为: afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); nChar 是所按键的字符代码值; nRepCnt 表示用户按键时重复击键的次数; nFlags 表示扫描码、先前键状态和键转换状态等。
(2)鼠标消息。在Windows中,处理鼠标操作基本上有下列三种: 单击(Click):表示按一下鼠标的左键或右键,然后释放; 双击(Double Click):表示快速连续按两下鼠标左键; 拖动(Drag):指按住鼠标的按键后,再移动鼠标。 所有这些鼠标操作,都会产生相应的消息。如下所示。
所有鼠标消息的处理函数都有很相似的原型,它们都有两个参数。以处理鼠标左键按下消息的函数OnLButtonDown()为例来进行说明。此函数的原型如下: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 参数point:是鼠标事件发生时鼠标光标所在的位置。 参数nFlags:指明鼠标按钮的状态以及鼠标事件发生时键盘上某些键的状态,每一状态都可以由nFlags的一位来表示。
(3)窗口消息。在MFC应用程序中,窗口消息是由视图类、窗口类及它们的派生类处理的。窗口消息往往带参数,并且各消息所带的参数各不相同。
2.控件消息 控件消息是指:控件或其他子窗口向父窗口发送WM_COMMAND消息或控件类所发送的消息。发送控件消息的控件在Visual C++中使用惟一的ID号来进行标识,使用控件类来操纵。 控件消息分为两类: (1)从控件传给系统的消息,通常这类消息的前缀的最后一个字符为N。 (2)由系统发送给控件的消息,这类消息前缀的最后一个字符为M。
3.命令消息 命令消息是指菜单项、工具栏按钮、加速键等用户界面对象发送的WM_COMMAND消息。它和控件消息的区别在于:控件消息只能由特定控件向Windows系统传送,而命令消息是由用户界面对象发送的,它可以被更多的对象处理。在文档对象、视图对象、窗体对象、控件对象中都能处理这种消息。发送命令消息的用户界面对象在Visual C++中是使用惟一的ID号来标识的
1.4 消息映射 通过消息映射,可以把消息和它的消息处理函数联系起来 。将主要用ClassWizard来捕获消息,进行消息映射,定义消息的处理函数。有三种方法来激活ClassWizard对话框: l (1) 选择View菜单下的ClassWizard菜单项。 l (2) 直接按键Ctrl+W。 l (3)当代码编辑窗口中有打开的文件时,可单击鼠标右键,在弹出的菜单中选择“建立类向导...”菜单项。
当执行了以上操作后,窗口中将弹出MFC ClassWizard对话框,如下图所示。
1.5 消息处理 1.5.1 消息的发送和接收 Windows接收消息、 响应消息的方式如右图所示。
1.5.2 消息处理的实例 1.鼠标消息举例 :该例子首先显示一个标准的Windows窗口,当用户在窗口中按下鼠标右键时,窗口中将弹出一个对话框,显示“鼠标左键被按下!”。按照下面的步骤进行操作。 步骤1:在Visual C++中选择“文件”(File)菜单的“新建”(New)菜单命令,弹出“新建”(New)对话框。在工程列表中选中选项MFC AppWizard“exe”,在“工程名”(Project name)栏中输入工程名称Mouse,在Location栏中指定工程的存储路径。单击OK按钮启动AppWizard。
步骤2:在接下来的AppWizard的各个步骤中按下列要求设置选项: (1)选择单文档界面(Single Document),其他接受系统设置。 (2)接受系统缺省设置。 (3)关闭ActiveX Controls复选框选项。 (4)关闭Printing and print preview复选框选项。 (5)接受系统缺省设置。 (6)接受系统缺省设置,单击Finish按钮,结束AppWizard。最后弹出工程信息对话框,单击OK按钮完成应用程序框架的设计。
步骤3:选择“查看”(View)—>“建立类向导”(ClassWizard)菜单命令。在弹出的MFC ClassWizard对话框中选择Message Maps选项卡。在Class name列表中选择CMouseView项,准备在视图类中处理鼠标消息。如下图所示。
步骤4:在Object IDs栏中选中CMouseView,在Messages栏中选择准备处理的消息,选中消息WM_LBUTTONDOWN,如下图所示。
步骤5:双击选中的消息,或者单击Add Function按钮,系统将在Member functions栏中自动添加相应的消息处理函数OnLButtonDown(),如下图所示。
步骤6:单击Edit Code按钮,ClassWizard将自动为该函数生成框架,同时在代码编辑窗口中显示这个函数,如下图所示。 添加如下代码: MessageBox("鼠标左键被按下!");
添加代码: MessageBox("鼠标右键被按下!"); 步骤7:点击“查看”菜单的“建立类向导..Ctrl+W”,并在MFC ClassWizard 的message中选择消息WM_RBUTTONDOWN,双击选中的消息,或者单击Add Function按钮,系统将在Member functions栏中自动添加相应的消息处理函数OnRButtonDown(),单击Edit Code按钮,ClassWizard将自动为该函数生成框架,同时在代码编辑窗口中显示这个函数。 添加代码: MessageBox("鼠标右键被按下!");
编译并运行该程序,您将会看到所创建的应用程序窗口。当在窗口中单击鼠标右键时,将弹出一个对话框,如下图所示。
2.键盘消息举例 步骤1:在上一题中,点击Workspace中的ClassView选项卡,如下图所示。用鼠标右键点击CMouseDoc类,在弹出的快捷菜单中点击Add Member Variable菜单命令
在弹出的对话框中,向Variable Type项中输入CString,在Variable name项中输入Text,如下图所示,点击“OK”按钮。
步骤2:在文档的构造函数中初始化Text。在Workspace中的ClassView选项卡中,用鼠标左键点击CMouseDoc前的“+”号,再双击成员函数CMouseDoc(),添加代码:Text="";如下图所示。
步骤3:生成消息响应函数。点击“查看”—>“建立类向导...Ctrl+W”,在Class name下拉列表中选择视图类CMouseView,在Object IDs列表框中选择CmouseView,在Messages列表中找到WM_CHAR,并双击选中的消息,或者单击Add Function按钮。系统将在Member functions栏中自动添加相应的消息处理函数OnChar()。添加代码(有底纹部分是手工加入的代码 ):
步骤4:显示输入字符串。在函数中加入以下代码(有底纹部分)。
编译并运行该程序,当在键盘输入时,键盘的可打印字符可显示在窗口中,如下图所示。