1第3章界面编程1-菜单Windows应用程序开发的基础是GUI的设计与编程,GUI包括WindowsAPI提供的窗口、菜单、对话框和控件等基本界面元素,以及MFC提供的工具栏和状态栏等组合控件,还有键盘和鼠标等消息响应与事件驱动。这些内容将在本书的第3~7章中逐个加以讨论,本章介绍菜单的设计与编程。3.1菜单菜单(menu)是传统GUI程序的主要命令接口,可用键盘和鼠标来访问。虽然菜单是基于文字串的,但是相对于(可视方便的)工具条和(直接快速的)快捷键,菜单所提供的程序功能更为完整和全面。默认的传统MFC应用程序,会在主框架窗口中自动生成一个菜单条(menubar)。菜单条也叫顶层菜单(top-levelmenu),一般包含文件、编辑、查看、窗口、帮助等若干下拉菜单。3.1.1菜单与菜单项菜单可分为包含若干菜单项的弹出菜单和发送命令消息的菜单项两大类,可以用键盘和鼠标这两种输入设备来访问菜单和菜单项(简记为“菜单[项]”)。1.菜单弹出菜单(pop-upmenu,简称为菜单)包含若干菜单项,一般处于(诸菜单项都不可见的)关闭状态。只有在用户(通过菜单名或按鼠标右键)激活菜单时,才由操作系统弹出来显示。并在用户通过选中菜单中的某个菜单项而发送对应的命令消息之后,又被操作系统自动关闭。(弹出)菜单又可以进一步分成(菜单条中的)下拉菜单(drop-downmenu)和(按鼠标右键后在光标处弹出的)快捷菜单(shortcutmenu),参见图3-1a)。弹出菜单中还可以包含若干(多级)子菜单,由其对应的(右端带的)菜单项激活,参见图3-1b)。2a)弹出菜单的种类b)多级子菜单图3-1菜单与菜单项2.菜单项菜单项(menuitem)用于发送程序的命令消息,一般由位于左端的图标或(表示选中的)勾符、简述命令功能的标题(caption)串、唯一标识资源的ID、详细说明命令功能的提示串、对应的加速键资源和事件处理函数等多个部分组成。其中的标题字符串又可包括:菜单名串、访问键、加速键指示串、(表示会弹出一个对话框)省略号“...”和(由系统在弹出菜单时自动生成的,表示对应于子菜单的右向黑三角)等内容,例如“打开(O)…Ctrl+O”、“工具栏(T)”、“类型(T)”等,参见图3-1。3.ID菜单项和其他所有的Windows资源一样,都有ID(IDentifier,标识符)。ID是一个(在全程序中具有唯一性的)非负整数,用于识别资源,供程序代码使用。在Windows编程中,为了便于人类阅读,ID通常是用(以下划线分隔的大写字母单词串组成的)符号常量来表示,如ID_FILE_OPEN。不过,在MFC编程中,一般不需要程序员手工编写符号常量ID的#define宏定义,而是在程序员设置资源的ID属性时,由资源编辑器自动生成。MFC应用程序中的所有ID定义,都位于项目目录下的资源头文件resource.h内。4.菜单类与对象在MFC类库中,菜单条和菜单都由CMenu类表示,它是对Windows菜单对象HMENU的类封装。CMenu类是直接从CObject的类派生的:CObject→CMenu3但是在MFC编程中一般不需要直接使用该类,除非你需要动态修改菜单[项]的内容。菜单对象属于主框架窗口,可先用从基类CWnd继承来的GetMenu函数CMenu*GetMenu()const;获得菜单条对象的指针(只是临时的,不能保存供以后使用),再用菜单类的成员函数GetSubMenuCMenu*GetSubMenu(intnPos)const;来获取指定的下拉式弹出菜单,其中nPos为菜单(从0开始的)位置序号。若想在视图类中获得程序的菜单对象,则必须先得到主框架窗口的指针,这可以使用从基类CWnd继承来的GetTopLevelFrame成员函数:CFrameWnd*GetTopLevelFrame()const;例如:CFrameWnd*pFrmWnd=GetTopLevelFrame();//获取主框架窗口CMenu*pMenu=pFrmWnd-GetMenu();//获取菜单条CMenu*pSubMenu=pMenu-GetSubMenu(3);//获取第4个菜单3.1.2访问键和快捷键访问键和快捷键都可用于菜单的快速键盘访问。1.访问键访问键(mnemonickey,助记键)也叫热键(hotkey)是菜单[项]标题字符串中出现的(可用对应的键盘按键快速访问的)带下划线的字符(一般为大写英文字母),例如菜单条上“文件(F)”菜单中的字母“F”和文件菜单中的“另存为(A)”菜单项的字母“A”。访问键的使用方法有如下两种:按“Alt+访问键”,可“选中”当前窗口菜单条上访问键所对应的菜单[项],例如按“Alt+F”会打开“文件(F)”菜单。按“访问键”本身,可“选中”当前已展开菜单中其所对应的菜单项,例如在已经打开的文件菜单中,按“A”会选中“另存为(A)...”菜单项,从而打开对应的“另存为”对话框。42.快捷键快捷键(shortcutkey)又叫加速键(acceleratorkey),是由菜单项标题串右端指明的功能键组合,一般为Ctrl/Alt/Shift+大写英文字母或功能键Fn。用快捷键可以直接访问当前窗口的任意菜单项(不论其所在的[子孙]菜单是否被展开),例如按“Ctrl+O”可以直接选中(尚未打开的)文件菜单中的“打开(O)...Ctrl+O”菜单项以打开对应的“打开”对话框。需要注意的是,在MFC编程中,菜单项的快捷键并不是由其标题中的指示串决定的,而是由项目的加速键资源决定的。因此,在设置完菜单项的各种属性之后,程序员还必须使用IDE的快捷键编辑器来将二者关联在一起。3.1.3默认菜单用MFC应用程序向导建立应用程序时,若选择的是单文档或多文档类型,而不是基于对话框类型,则会自动建立预定义的菜单条。1.单文档程序传统的单文档界面MFC应用程序只有一个菜单条,默认时含“文件”、“编辑”、“查看”、“帮助”4个下拉菜单(参见图3-1a)),菜单条的ID为IDR_MAINFRAME。2.多文档程序传统的多文档界面MFC应用程序有两个菜单条:主框架菜单条:在程序刚启动或没有任何文档子窗口时显示,默认时含“文件”、“查看”、“帮助”3个下拉菜单,菜单条的ID也为IDR_MAINFRAME。文档菜单条:在程序有文档子窗口时显示,默认时含“文件”、“编辑”、“查看”、“窗口”、“帮助”5个下拉菜单(增加了一个“窗口”下拉菜单,参见图2-37),ID为IDR_*TYPE,其中*表示应用程序的项目名,例如IDR_TestTYPE。3.1.4菜单资源在MFC应用程序项目中,菜单资源和其他资源一样,都是以文本方式存在于资源脚本文件中,而对应的资源ID则被定义在资源头文件中。5在默认情况下,VC以可视的“资源编辑器”方式来打开资源文件,让程序员进行交互式菜单设计。用资源编辑器编辑菜单等资源的结果,都会被自动保存在这两个资源文件之中。1.查看资源文本资源文件指位于MFC应用程序项目目录中的资源脚本文件“项目名.rc”(如Student.rc)和资源头文件Resource.h。似C++头文件和代码文件,也可以用任何文本编辑器(如Windows自带的记事本和写字板),来可以查看和编辑资源头文件和资源脚本文件。也可以用VC来查看和编辑资源文件中的源代码文本。在VC中,以文本方式来打开资源文件的做法有三种(都需先关闭资源编辑器):方法1:在项目区中选中“解决方案资源管理器”页,选中应用程序的“资源文件\*.rc”。按鼠标右键,在弹出的快捷菜单中,选“查看代码”菜单项,参见图3-2a)。方法2:在项目区中选中“解决方案资源管理器”页,选中应用程序的“资源文件\*.rc”。按鼠标右键,在弹出的快捷菜单中,选“打开方式”菜单项,也参见图3-2a)。在弹出的“打开方式”对话框中,选中“源代码(文本)编辑器”项,按“确定”关闭对话框,参见图3-2b)。a)文件快捷菜单b)打开方式对话框图3-2以文本方式打开资源文件方法3:6在“打开文件”对话框中,选“打开”按钮右端的钮打开下拉式列表,选中其中的“打开方式(W)...”项。在弹出的“打开方式”对话框中,选中“源代码(文本)编辑器”项,按“确定”关闭对话框,参见图3-2b)。作为参考,下面给出由MFC应用程序向导自动生成的Student程序的默认资源头文件(Resource.h)和菜单资源文本的内容(位于资源脚本文件Student.rc中)。2.资源头文件VC在资源头文件Resource.h中定义各种ID符号常量,这些定义由MFC应用程序向导或资源编辑器自动生成,一般不需要自己手工修改。下面是Student程序的初始资源头文件的内容://{{NO_DEPENDENCIES}}//MicrosoftVisualC++generatedincludefile.//UsedbyStudent.rc//#defineIDD_ABOUTBOX100#defineIDP_OLE_INIT_FAILED100#defineIDR_MAINFRAME128#defineIDR_StudentTYPE130//新对象的下一组默认值//#ifdefAPSTUDIO_INVOKED#ifndefAPSTUDIO_READONLY_SYMBOLS#define_APS_NEXT_RESOURCE_VALUE310#define_APS_NEXT_CONTROL_VALUE1000#define_APS_NEXT_SYMED_VALUE310#define_APS_NEXT_COMMAND_VALUE32771#endif7#endif2.资源脚本文件在MFC项目中,用资源脚本文件“项目名.rc”(后缀rc=resource,资源)来描述程序的各种资源,包括:包含文本、图标、位图、工具栏、菜单、快捷键、对话框、版本、设计信息、字符串表等资源。下面是Student程序的资源脚本文件Student.rc中的默认菜单资源部分://///////////////////////////////////////////////////////////////////菜单//IDR_MAINFRAMEMENUBEGINPOPUP文件(&F)BEGINMENUITEM新建(&N)\tCtrl+N,ID_FILE_NEWMENUITEM打开(&O)...\tCtrl+O,ID_FILE_OPENMENUITEM保存(&S)\tCtrl+S,ID_FILE_SAVEMENUITEM另存为(&A)...,ID_FILE_SAVE_ASMENUITEMSEPARATORMENUITEM打印(&P)...\tCtrl+P,ID_FILE_PRINTMENUITEM打印预览(&V),ID_FILE_PRINT_PREVIEWMENUITEM打印设置(&R)...,ID_FILE_PRINT_SETUPMENUITEMSEPARATORMENUITEM最近的文件,ID_FILE_MRU_FILE1,GRAYEDMENUITEMSEPARATORMENUITEM退出(&X),ID_APP_EXITEND8POPUP编辑(&E)BEGINMENUITEM撤消(&U)\tCtrl+Z,ID_EDIT_UNDOMENUITEMSEPARATORMENUITEM剪切(&T)\tCtrl+X,ID_EDIT_CUTMENUITEM复制(&C)\tCtrl+C,ID_EDIT_COPYMENUITEM粘贴(&P)\tCtrl+V,ID_EDIT_PASTEENDPOPUP视图(&V)BEGINMENUITEM工具栏(&T),ID_VIEW_TOOLBARMENUITEM状态栏(&S),ID_VIEW_STATUS_BARENDPOPUP帮助(&H)BEGINMENUITEM关于Student(&A)...,ID_APP_ABOUTENDEND3.2设计菜单