工具栏和状态栏

上传人:新** 文档编号:567593521 上传时间:2024-07-21 格式:PPT 页数:60 大小:771.50KB
返回 下载 相关 举报
工具栏和状态栏_第1页
第1页 / 共60页
工具栏和状态栏_第2页
第2页 / 共60页
工具栏和状态栏_第3页
第3页 / 共60页
工具栏和状态栏_第4页
第4页 / 共60页
工具栏和状态栏_第5页
第5页 / 共60页
点击查看更多>>
资源描述

《工具栏和状态栏》由会员分享,可在线阅读,更多相关《工具栏和状态栏(60页珍藏版)》请在金锄头文库上搜索。

1、第四章菜单、工具栏和状态栏第四章菜单、工具栏和状态栏4.1菜单菜单4.2工具栏工具栏4.3状态栏状态栏4.4交互对象的动态更新交互对象的动态更新4.5综合应用综合应用辑苗腕霍石濒望销吧疟革续倚蔫贩鼓究戒惮掂窥沿钉渠壳了毁释颊臃居糖工具栏和状态栏工具栏和状态栏4.1菜单菜单 菜单是一系列命令的列表,通过选中其中的菜单项(命令)来执行相应任务。除一些简单的基于对话框的应用程序外,所有的Windows应用程序都提供了各自的菜单。 为了使应用程序更容易操作,对于菜单系统的设计还遵循下列一些规则: 若单击某菜单项后,将弹出一个对话框,那么在该菜单项文本后有“”。 若某项菜单有子菜单,那么在该菜单项文本后

2、有“”。 若菜单项需要助记符,则用括号将带下划线的字母括起来。助记符与Alt构成一个组合键,当按住“Alt”键不放,再敲击该字母时,对应的菜单项就会被选中。 若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。所谓“快捷键”是一个组合键,如Ctrl+N,使用时是先按下“Ctrl”健不放,然后再按“N”键。任何时候按下快捷键,相应的菜单命令都会被执行。 图4.1是一个菜单样例,注意它们的规则含义。需要说明的是,在常见的菜单系统中,最上面的一层水平排列的菜单称为顶层菜单顶层菜单,每一个顶层菜单项可以是一个简单的菜单命令,也可以是下拉下拉(Popup)菜单,在下拉菜单中的每一个菜单项也可是

3、菜单命令或下拉菜单,这样一级一级下去可以构造出复杂的菜单系统。赞那骚氧获细椎晤匝块响抽蜀雷辊捡股搜谋揪窃渡亚猫夕拣而全歧完矢势工具栏和状态栏工具栏和状态栏4.1菜单菜单顶层菜单顶层菜单下拉菜单下拉菜单图图4.1 菜单样例菜单样例坯罢欧肩锭犯蛇展玖习翘司凶珠林士予遇厉旁握霜兔迈形谰孪楔羔忘挥钾工具栏和状态栏工具栏和状态栏4.1菜单菜单 4.1.1 用编辑器设计菜单 1. 编辑菜单编辑菜单 (1)在顶层菜单的最后一项,Visual C+自动留出了一个空位置,用来输入新的顶层菜单项。在菜单的空位置上双击鼠标左键,出现菜单项的属性对话框,在标题框中输入“测试(&T)”,结果如图4.2所示,其中符号&用

4、来将其后面的字符作为该菜单项的助记符,这样当按住“Alt”键不放,再敲击该助记符键时,对应的菜单项就会被选中,或在菜单打开时,直接按相应的助记符键,对应的菜单项也会被选中。子菜单的空位置子菜单的空位置顶层菜单的空位顶层菜单的空位置置图图4.2 Ex_SDI菜单资源菜单资源莉倔悉宜卸愧腺撬触柱独夷朱算氛旱龚蓑柏甸生姆畴慧醇腋悄璃褒渣井桓工具栏和状态栏工具栏和状态栏4.1菜单菜单 需要说明的是,Visual C+将顶层菜单项的默认属性定义为“弹出”(下拉)菜单,即该菜单项有下拉式子菜单。一个含有下拉子菜单的菜单项是不需要相应的ID标识符。同时,“弹出”菜单项的属性对话框中,ID、分隔符(Separ

5、ator)和提示(Prompt)项无效。表4.1列出菜单属性对话框“常规”(General)的各项含义。表表4.1 菜单菜单General属性对话框的各项含义属性对话框的各项含义项项 目目含含 义义ID菜单的资源ID标识符标题(Caption)用来标识菜单项显示文本。助记符字母的前面须有一个&符号,这个字母与Alt构成组合键。分隔符(Separator)选中时,菜单项是一个分隔符或是一条水平线已复选(Checked)选中时,菜单项文本前显示一个选中标记弹出(Pop_up)选中时,菜单项含有一个弹出式子菜单已变灰(Grayed)选中时,菜单项显示是灰色的,用户不能选用非活动(Inactive)选

6、中时,菜单项没有被激活,用户不能选用帮助(Help)选中时,菜单项在程序运行时被放在顶层菜单的最右端中断(Break,分块)当为“列”(Column)时,对于顶层菜单上的菜单项来说,被放置在另外一行上,而对于弹出式子菜单的菜单项来说,则被放置在另外一列上;当为“条”(Bar)时,与Column相同,只不过对于弹出式子菜单来说,它还在新列与原来的列之间增加一条竖直线;注意这些效果只能在程序运行后才能看到。提示(Prompt)用来指明光标移至该菜单项时在状态栏上显示的提示信息殖香凿裂圆即掩化摩润獭神哨眩石牢斯呼白膛衣脚捕骨碎录牌披坯步尤验工具栏和状态栏工具栏和状态栏4.1菜单菜单 (2)单击“测试

7、”菜单项下方的空位置,在菜单项属性对话框中,输入标题“切换菜单(&D)”,在ID框输入该菜单项的资源标识符:ID_TEST_CHANGE,结果如图4.3所示。图图4.3 修改菜单项属性修改菜单项属性 (3)关闭菜单项属性对话框,单击“测试”菜单项并按住鼠标左键不放,移动鼠标,将“测试”菜单项移到“查看”和“帮助”菜单项之间,然后释放鼠标。结果如图4.4所示。这样,就将新添加的“测试”菜单项拖放到“查看”和“帮助”菜单项之间了。需要说明的是,菜单项位置改变后,其属性并没改变。图图4.4 菜单项菜单项“测试测试”拖放后的位置拖放后的位置物胖角爹镜绷斯先臼仅谁栈探姜那纳恼榷诉不裳站境患摧帐厨曹痈窑菠

8、龙工具栏和状态栏工具栏和状态栏4.1菜单菜单2. 菜单命令的消息映射菜单命令的消息映射 菜单项、工具栏的按钮以及快捷键等用户交互对象都能产生WM_COMMAND命令消息。命令消息能够被文档类、应用类、窗口类以及视图类等多种对象接收、处理,且用户可以用ClassWizard对命令消息进行映射。例如,上述的“切换菜单”菜单项的命令映射过程如下: (1)选择“查看”“建立类向导”菜单命令或按Ctrl+W快捷键,则出现MFC ClassWizard对话框,并自动切换到Message Maps页面。 (2)从“Class name”列表中选择CMainFrame,在IDs列表中选择ID_TEST_CHA

9、NGE,然后在Messages框中选择COMMAND消息。单击Add Function按钮或双击COMMAND消息,出现“Add Member Function”对话框以输入成员函数的名称。系统默认的函数名为OnTestChange,如图4.5所示。该函数是对菜单项ID_TEST_CHANGE的映射,也就是说,当应用程序运行后,用户选择“测试”“切换菜单”菜单时,该函数OnTestChange被调用,执行函数中的代码。特熏烧蹄喀徊粉匝哎最搂咀摸剿校肛除乳景收远玻鼠凉搅阿舱螺构容负恿工具栏和状态栏工具栏和状态栏4.1菜单菜单图图4.5 菜单命令消息的映射菜单命令消息的映射厌创爱恶可址翱在譬堤按乓

10、柠弄泞睫姐伏蔚共钒熔榷肾健抄瞪杰底帅圈寄工具栏和状态栏工具栏和状态栏4.1菜单菜单 (3)单击OK按钮,在ClassWizard的“Member functions”列表中将列出新增加的成员函数。选择此函数,单击Edit Code按钮(或直接在函数名双击鼠标),在此成员函数中添加下列代码: void CMainFrame:OnTestChange() MessageBox(现在就切换吗?); (4)编译运行并测试。在应用程序的顶层菜单上,单击“测试”菜单项,然后将鼠标移动到弹出的子菜单项“切换菜单”上,则结果如图4.6所示,此时状态栏上显示该菜单项的提示信息,该信息就是在前图4.3的菜单项属性

11、对话框“提示”框中设置的内容。单击“切换菜单”,则弹出一个消息对话框,显示内容“现在就切换吗?”。图图4.6 Ex_SDI运行后的菜单运行后的菜单辰约爹牙淫火泅栈稼斡沾孽驹殉疟片曳沤祭吻剁淮缎捕是威奸麦息召摧朽工具栏和状态栏工具栏和状态栏4.1菜单菜单 4.1.2 使用键盘快捷键通过菜单系统,可以选择几乎所有可用的命令和选项,它保证了菜单命令系统的完整性,但菜单系统也有某些美中不足之处,如操作效率不高等。尤其对于那些反复使用的命令,很有必要进一步提高效率,于是加速键应运而生。 加速键加速键也往往被称为键盘快捷键键盘快捷键,一个加速键就是一个按键或几个按键的组合,它用于激活特定的命令。加速键也是

12、一种资源,它的显示、编辑过程和菜单相似。例如下面的过程是为前面菜单项ID_TEST_CHANGE定义一个键盘快捷键: (1)在项目工作区窗口的ResourceView(资源视图)页面中,展开中Accelerator(加速键)的资源项,双击IDR_MAINFRAME,在右侧窗口中出现如图4.7的加速键资源列表。 下端的空行下端的空行图图4.7 Ex_SDI的加速键资源的加速键资源别估络疥窝蔬鲤室挞崩岔栏兢授懂躁吠照壁耙汤妥白鞠梗转啥榷窿浊冲融工具栏和状态栏工具栏和状态栏4.1菜单菜单 (2)建立一个新的加速键时,只要双击加速键列表的最下端的空行,弹出如图4.8所示的“Accel 属性”(Acce

13、l Properties)对话框,其中可设置的属性如表4.2所示图图4.8 加速键属性对话框加速键属性对话框表表4.2 加速键常规(加速键常规(General)属性的各项含义)属性的各项含义项项 目目含含 义义ID指定资源ID号的列表项,为了能和菜单联用,通常选择某菜单项的ID号辅助键(Modifiers)用来确定Ctrl、Alt、Shift是否是构成加速键的组成部分类型(Type)用来确定该加速键的值是虚拟键(VirKey)还是ASCII字符键键(Key)是指启动加速键的键盘按键下一键(Next Key Typed)单击此按钮后,用户操作的任何按键将成为此加速键的键值若铭袁毛靶儒诧归石凯峨碟

14、砚搐勺窿汰汁慈谦膨抄弱顿蔚硒疚令脱吹咨蒙工具栏和状态栏工具栏和状态栏4.1菜单菜单 需要说明的是,为了使其他用户能查看并使用该加速键,还需在相应的菜单项文本后面添加加速键内容。例如,可将ID_TEST_CHANGE菜单项的标题改成“切换菜单 (&C)tCtrl+1”,其中“t”是将后面的“Ctrl+1”定位到下一个水平制表位。 (4)编译运行并测试。当程序运行后,按Ctrl+1键将执行相应的菜单命令。 4.1.3 更改应用程序菜单 下面就上节的单文档应用程序Ex_SDI的基础上,为其添加菜单资源并实现应用程序的菜单更改。如下面的过程: (1)按快捷键Ctrl+R,弹出“插入资源”对话框,在资源

15、类型中选定“Menu”,如图4.9。图图4.9 “插入资源插入资源”对话框对话框 (3)在加速键属性对话框中,先选择在Ex_SDI应用程序菜单资源添加的“切换菜单”菜单项ID_TEST_CHANGE作为要联用的加速键的ID标识符,然后单击下一键按钮,并按下Ctrl+1作为此加速键的键值。槽谤要史呛羌獭靳乓呵行啥水控悸川窟猖哟瓦朴建盈存矾释阀烧祖烘抬远工具栏和状态栏工具栏和状态栏4.1菜单菜单 (2)单击新建按钮,系统就会为应用程序添加一个新的菜单资源,并自动赋给它一个默认的标识符名称(第一次为IDR_MENU1,以后依次为IDR_MENU2、IDR_MENU3、.),同时自动打开这个新的菜单资

16、源及相应的菜单编辑器,如图4.10所示。 (3)在Menu资源的ID_MENU1上右击鼠标,从弹出的快捷菜单中选择“属性”(Properties)命令,出现如图4.11所示的菜单属性对话框,在这里可以重新指定菜单资源ID,设置菜单资源的语言和条件,这个条件用来决定菜单资源包含到哪个环境中,例如当指定条件为_DEBUG,则菜单资源只存在于Debug编译环境中。 菜单空位置菜单空位置 菜单默认菜单默认ID图图4.10 添加菜单资源后的开发环境添加菜单资源后的开发环境图图4.11 菜单属性对话框菜单属性对话框堆预樟怖腺液墩揭拜腊溯泳毙矮筑障痊漳酣巷蠢俗嘎廊伶台淑叛蓉笆践快工具栏和状态栏工具栏和状态栏

17、4.1菜单菜单 (4)在菜单的空位置上双击鼠标左键,则出现它的属性对话框。通过其属性对话框为菜单ID_MENU1添加一个顶层弹出菜单项“测试(&T)”,并在该菜单下添加一个子菜单项“返回(&R)”,ID设为ID_TEST_RETURN,如图4.12所示。需要再次强调的是,符号&用来指定后面的字符是一个助记符。图图4.12 设计新的菜单资源设计新的菜单资源 (5)为CMainFrame类添加一个CMenu类型的成员变量m_NewMenu,CMenu类是用来处理菜单的一个MFC类。拭胜甥葫炎擦志瘁迟说或羊侨无陈陌煮责四咸玛龚瞬萍每戒喊碾烹链港蚁工具栏和状态栏工具栏和状态栏4.1菜单菜单 (6)按快

18、捷键Ctrl+W打开MFC ClassWizard对话框,切换到Message Maps页面,从“Class name”列表中选择CMainFrame,为菜单项ID_TEST_RETURN添加COMMAND消息映射,使用默认的消息映射函数名,并添中下列代码: void CMainFrame:OnTestReturn() m_NewMenu.Detach();/ 使菜单对象和菜单句柄分离 m_NewMenu.LoadMenu( IDR_MAINFRAME ); SetMenu(NULL); / 清除应用程序菜单 SetMenu( &m_NewMenu );/ 设置应用程序菜单 代码中,LoadM

19、enu和Detach都是CMenu类成员函数,LoadMenu用来装载菜单资源,而Detach是使菜单对象与菜单句柄分离。在调用LoadMenu后,菜单对象m_NewMenu就拥有一个菜单句柄,当再次调用LoadMenu时,由于菜单对象的句柄已经创建,因而会发生运行时错误,但当菜单对象与菜单句柄分离后,就可以再次创建菜单了。SetMenu是CWnd类的一个成员函数,用来设置应用程序的菜单。蝉卡抗揍械涡设镀彝剁半躁经荐灾吼早半贤臃桔婴溃堕圈芥芦霉鬃坦炸细工具栏和状态栏工具栏和状态栏4.1菜单菜单 (7)修改CMainFrame:OnTestChange中的代码: void CMainFrame:

20、OnTestChange() / MessageBox(现在就切换吗?); m_NewMenu.Detach(); m_NewMenu.LoadMenu( IDR_MENU1 ); SetMenu(NULL); SetMenu( &m_NewMenu ); (8)编译运行后,选择Ex_SDI应用程序的“测试”“切换菜单”菜单命令,菜单栏变成了新添加的IDR_MENU1,在新的菜单中选择“测试”“返回”菜单命令,程序又变回到了原来的主菜单了。警卓拒铸蚜颈战万泌奴林楔线慕腊佳召瑶你遥凌尔篮瘴骇聪粹闺仅沏催凄工具栏和状态栏工具栏和状态栏4.1菜单菜单 4.1.4 菜单的编程控制 1. 创建菜单创建菜

21、单 CMenu类的CreateMenu和CreatePopupMenu分别用来创建一个菜单或子菜单框架,它们的原型如下: BOOL CreateMenu( ); / 产生一个空菜单 BOOL CreatePopupMenu( );/ 产生一个空的弹出式子菜单 2. 装入菜单装入菜单 将菜单从资源装入应用程序中,需调用CMenu成员函数LoadMenu,或者用SetMenu对应用程序菜单进行重新设置。 BOOL LoadMenu( LPCTSTR lpszResourceName ); BOOL LoadMenu( UINT nIDResource ); 其中,lpszResourceName为

22、菜单资源名称,nIDResource为菜单资源ID标识符。 3. 添加菜单项添加菜单项 当菜单创建后,用户可以调用AppendMenu或InsertMenu函数来添加一些菜单项。但每次添加时,AppendMenu是将菜单项添加在菜单的末尾处,而InsertMenu在菜单的指定位置处插入菜单项,并将后面的菜单项依次下移。嘱求湍桥气琅域坷钟或挂快虹胁蛙还修诚粱狈满兑霜粳蛊黄哮叭年叁乔渗工具栏和状态栏工具栏和状态栏4.1菜单菜单 BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL ); BOOL A

23、ppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ); BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ); BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ); 其中,nIDNewItem表示新菜单项的资源ID标识符,lpszNewItem表示新菜单项的内容,pBmp

24、用于菜单项的位图指针,nPosition表示新菜单项要插入的菜单项位置。nFlags表示要增加的新菜单项的状态信息,它的值影响其他参数的含义,如表4.3所示。莎品象俞磨篮掘窗酷致紧敏蛇综胜圣挤佑努铰内渔逆厕仕若录晴蔬全远拔工具栏和状态栏工具栏和状态栏4.1菜单菜单表表4.3 nFlags的值及其对其他参数的影响的值及其对其他参数的影响nFlags值值含含 义义nPosition值值nIDNewItem值值lpszNewItem值值MF_BYCOMMAND菜单项以ID标识符来标识菜单项资源IDMF_BYPOSITION菜单项以位置来标识菜单项的位置MF_POPUP菜单项有弹出式子菜单弹出式菜单句

25、柄MF_SEPARATOR分隔线忽略忽略MF_OWNERDRAW自画菜单项自画所需的数据MF_STRING字符串标志字符串指针MF_CHECKED设置菜单项的选中标记MF_UNCHECKED取消菜单项的选中标记MF_DISABLED禁用菜单项MF_ENABLED允许使用菜单项MF_GRAYED菜单项灰显棵汁子裙劫益版爵瓤壮篱洽僧因亩潞瞧蒋哮施蚜篷榴网讳淖鬼槽销灭惕瞳工具栏和状态栏工具栏和状态栏4.1菜单菜单 需要注意的是: 当nFlags为MF_BYPOSITION时,nPosition表示新菜单项要插入的具体位置,为0时表示第一个菜单项,为 -1时,将菜单项添加菜单的末尾处。 nFlags的

26、标志中,可以用“|”(按位或)来组合,例如MF_CHECKED|MF_STRING等。但有些组合是不允许的,例如MF_DISABLED、MF_ENABLED和MF_GRAYED,MF_STRING、MF_OWNERDRAW、MF_SEPARATOR和位图,MF_CHECKED和MF_UNCHECKED 都不能组合在一起。 当菜单项增加、改变或删除后,不管菜单依附的窗口是否改变,都应调用CWnd: DrawMenuBar来更新菜单。 4. 删除菜单项删除菜单项 调用DeleteMenu函数可将指定的菜单项删除,函数DeleteMenu的原型如下: BOOL DeleteMenu( UINT nP

27、osition, UINT nFlags ); 其中,参数nPosition表示要删除的菜单项位置,它由nFlags进行说明。若当nFlags为MF_BYCOMMAND时,nPosition表示菜单项的ID标识符,而当nFlags为MF_BYPOSITION时,nPosition表示菜单项的位置(第一个菜单项位置为0)。 底蒂康瘁甚咖告请岿旗万遍藉匡溜卡壬恬汰浓阮绽笼郡锯凌幅炕拍哼鸦鬼工具栏和状态栏工具栏和状态栏4.1菜单菜单5. 获取菜单项获取菜单项 下面的3个CMenu成员函数分别获得菜单的项数、菜单项的ID标识符以及弹出式子菜单的句柄。 UINT GetMenuItemCount( )

28、const; 该函数用来获得菜单的菜单项数,调用失败后返回-1。 UINT GetMenuItemID( int nPos ) const; 该函数用来获得由nPos指定菜单项位置(以0为基数)的菜单项的标识号,若nPos是SEPARATOR(分隔符),则返回-1。 CMenu* GetSubMenu( int nPos ) const; 该函数用来获得指定菜单的弹出式菜单的菜单句柄。该弹出式菜单位置由参数nPos指定,开始的位置为0。若菜单不存在,则创建一个临时的菜单指针。 例例Ex_Menu 用程序添加并处理一个菜单项用程序添加并处理一个菜单项 下面的示例过程是利用CMenu成员函数向应用

29、程序菜单中添加并处理一个菜单项: (1)创建一个默认的单文档应用程序Ex_Menu。 (2)选择“查看”“资源符号”(Resource Symbols)命令,弹出如图4.13所示的“资源符号”对话框,它能对应用程序中的资源标识符进行管理。慕码卞彻肯扶这铰嚼络扣舆鄙祭殷箍乾循内拜缺锯臀金宾叫形馏漓唾犁垦工具栏和状态栏工具栏和状态栏4.1菜单菜单图图4.13 “资源符号资源符号”对话框对话框菜单项的资源值用资源标识符来表示,是一个好的习惯。在为项目用程序来添加一个菜单项时,为了能使框架使用到这个菜单项,常用此对话框来添加一个新标识符。后巾哟彦筋荡撼哉惩稽沛末所体仪柜橡馏兑诛操二降鹊硬涅氯盅径跌毛吟

30、工具栏和状态栏工具栏和状态栏4.1菜单菜单 (3)单击新建按钮,弹出如图4.14所示的“新建符号”(New Symbol)对话框。在“名称”(Name)框中输入一个新的标识符ID_NEW_MENUITEM。在“值”(Value)框中,输入该ID的值,系统要求用户定义的ID值应大于15(0X000F)而小于61440(0XF000)。保留默认的ID值101,单击确定按钮,关闭“资源符号”对话框。图图4.14 新标识符对话框新标识符对话框羌狼违乐奶御菩瓮夹燕踊棵峪镍郡钧透骏洗嘛销窿牛烛棉赛撼本鹰蓬磐短工具栏和状态栏工具栏和状态栏4.1菜单菜单 (4)在CMainFrame:OnCreate函数中添

31、加下列代码,该函数在框架窗口创建时自动调用。 int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) . CMenu* pSysMenu = GetMenu();/ 获得程序菜单指针 CMenu* pSubMenu = pSysMenu-GetSubMenu(1); / 获得第二个子菜单的指针 CString strMenuItem(新的菜单项); pSubMenu-AppendMenu(MF_SEPARATOR);/ 增加一水平分隔线 pSubMenu-AppendMenu(MF_STRING,ID_NEW_MENUITEM, strMe

32、nuItem);/ 在子菜单中增加一菜单项 m_bAutoMenuEnable = FALSE; / 关闭自动更新菜单状态,这样避免添加的菜单项是禁用的 pSysMenu- EnableMenuItem(ID_NEW_MENUITEM,MF_BYCOMMAND|MF_ENABLED);/ 激活菜单项 DrawMenuBar();/ 更新菜单 return 0; 带妇淬诗薄御亚佯踪络聊嗽俯剁溯痪宵迂熊伍淄展缉挛羔仰叭卞惯尝器疗工具栏和状态栏工具栏和状态栏4.1菜单菜单(5)此时编译运行后,结果如图4.15所示。但此时选择“新的菜单项”命令不会有反应。图图4.15 程序添加的菜单项程序添加的菜单项

33、 (6)用MFC ClassWizard在CMainFrame添加OnCommand消息函数的重载,并添加下列代码: BOOL CMainFrame:OnCommand(WPARAM wParam, LPARAM lParam) / wParam的低字节表示菜单、控件、加速键的命令ID if (LOWORD(wParam) = ID_NEW_MENUITEM) MessageBox(你选中了新的菜单项); return CFrameWnd:OnCommand(wParam, lParam); 讨扼母崩俞硒潦宫蛇毗吓幻寨井沛甫灿奇肇蛀尚崩诗浑笼旷渴蔷浑彰郁挟工具栏和状态栏工具栏和状态栏4.1菜单

34、菜单 (7)编译运行并测试。这时当选择菜单“编辑”“新的菜单项”命令后,就会弹一个对话框,显示“你选中了新的菜单项”消息。 4.1.5 使用快捷菜单 快捷菜单快捷菜单是一种浮动的弹出式菜单,它是一种较新的用户界面设计风格。当用户按下鼠标右键时,就会相应地弹出一个浮动菜单,提供了几个与当前选择内容相关的菜单选项。 用资源编辑器和MFC库的CMenu:TrackPopupMenu函数可以很容易地创建这样的菜单,CMenu:TrackPopupMenu函数原型如下: BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT

35、 lpRect = NULL ); 该函数用来显示一个浮动的弹出式菜单,其位置由各参数决定。其中,nFlags表示菜单在屏幕显示的位置以及鼠标按钮标志,如表4.4所示。x和y表示菜单的水平坐标和菜单的顶端的垂直坐标。pWnd表示弹出菜单的窗口,此窗口将收到菜单全部的 WM_COMMAND消息。lpRect是一个RECT结构或CRect类指针,它表示一个矩形区域, 用户单击这个区域时,弹出菜单不消失。而当lpRect为NULL时,若用户击在菜单外面, 菜单立刻消失。落姻酉筏俗郊钧填诱陶揪授斩炉少茶挑淫姑曾新缝唇志超美斗习备洲保开工具栏和状态栏工具栏和状态栏4.1菜单菜单表表4.4 nFlags的

36、值及其对其他参数的影响的值及其对其他参数的影响nFlags值值含含 义义TPM_CENTERALIGN屏幕位置标志,表示菜单的水平中心位置由x坐标确定TPM_LEFTALIGN屏幕位置标志,表示菜单的左边位置由x坐标确定TPM_RIGHTALIGN屏幕位置标志,表示菜单的右边位置由x坐标确定TPM_LEFTBUTTON鼠标按钮标志,表示当用户单击鼠标左键时弹出菜单TPM_RIGHTBUTTON鼠标按钮标志,表示用户单击鼠标右键时弹出菜单 下面来看一个示例,由于右击鼠标时会向系统发送WM_CONTEXTMENU通知消息,因此通过该通知消息,并在映射函数中添加快捷菜单的相关代码。 例例Ex_Con

37、textMenu 使用快捷菜单使用快捷菜单 (1) 创建一个默认的单文档应用程序Ex_ContextMenu。淖峭抽茄申牺打妮划惨村翘炽誉抗娱知灰掏附劈四秒北涂旷竹祖撰颗迂磁工具栏和状态栏工具栏和状态栏4.1菜单菜单 (2)用MFC ClassWizard在CEx_ContextMenuView类添加WM_CONTEXTMENU消息映射,并在映射函数中添加下列代码: (3)在Ex_ContextMenuView.cpp文件的前面添加CMainFrame类的文件包含: #include Ex_ContextMenuView.h #include MainFrm.h (4)运行并测试。当用户在应用

38、程序窗口的客户区中右击鼠标,会弹出如图4.16的快捷菜单。图图4.16 快捷菜单快捷菜单育雹驱侦蚤篆泊准输酣誉歇葱咆筹历壹孟韦晴孔妆茵烷掸桶饯孽而莹晾泰工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 4.2.1 使用工具栏编辑器 选择菜单“文件”“打开工作空间(区)”,将前面的单文档应用程序Ex_SDI调入。在项目工作区窗口中选择ResourceView页面,双击“Toolbar”项中的IDR_MAINFRAME,则在主界面的右边出现工具栏编辑器,如图4.17所示。空按钮空按钮图形工具箱图形工具箱颜色工具箱颜色工具箱图图4.17 工具栏编辑器窗口工具栏编辑器窗口渐昏涛欺葱私佰购伍拢掣软县柬笛鸡

39、音杨泣鞭墨憋敬釉僳监余砖镣篆剁泌工具栏和状态栏工具栏和状态栏4.2工具栏工具栏1. 创建一个新的工具栏按钮创建一个新的工具栏按钮 在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在ID框中输入其标识符名称,则在其右端又出现一个新的空按钮。单击该按钮,在资源编辑器的工具按钮设计窗口内进行编辑,这个编辑就是绘制一个工具按钮的位图,它同一般图形编辑器操作相同(如Windows系统中的“画图”附件)。 2. 移动一个按钮移动一个按钮 在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相应位置即可。若拖动它离开工具栏位置,则此按钮从工具栏中消失。若在移动一个按钮的同时,按下Ctrl键,

40、则在新位置复制一个按钮,新位置可以是同一个工具栏中的其他位置,也可以在不同的工具栏中。 3. 删除一个按钮删除一个按钮 前面已提到过,将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中按钮后,单击Delete键并不能删除一个按钮,只是将按钮中的图形全部以背景色填充。 4. 在工具栏中插入空格在工具栏中插入空格 在工具栏中插入空格有以下几种情况:汾连先屉天凝搁林涕囱奋烦早卡昨描缮社舞位友吱丁舆鼻僚甥勒练工陛徐工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 如果按扭前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。 如果按钮前有空格而按钮后没有空格,

41、拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。 如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相 邻按钮时,则此按钮前面的空格消失,后面的空格保留。 5. 工具栏按钮属性的设置工具栏按钮属性的设置 双击某按钮弹出其属性对话框,如图4.18所示。属性对话框中的各项说明见表4.5。图图4.18 工具栏按钮属性对话框工具栏按钮属性对话框艰娟点喧帮揉霜滨义沧锚颠皑加佩汗摊闻湿趴任快藉永防督堑即赦违亢阑工具栏和状态栏工具栏和状态栏4.2工具栏工具栏表表4.5 工具栏按钮

42、属性的各项含义工具栏按钮属性的各项含义项项 目目含含 义义ID工具栏按钮的标识符,用户既可以输入自己的标识符名称,也可从ID框的下拉列表中选取标识符名称宽度(Width)工具栏按钮的象素宽度高度(Height)工具栏按钮的象素高度提示(Prompt)工具栏按钮提示文本;若为“建立新文档n新建”,则表示将鼠标指向该按钮时,在状态栏中显示“建立新文档”,而在弹出按钮的提示信息中出现“新建”字样。“n”是它们的分隔转义符敲忠竭硅峰住炭技庚匠迄氏阎晰轿绽勃庚温耙城打咕镁客亚缘誊掏髓约冷工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 例例Ex_TM 工具按钮和菜单项相结合工具按钮和菜单项相结合 (1)创

43、建一个默认的单文档应用程序Ex_TM。 (2)在项目工作区窗口中选择ResourceView页面,展开结点,双击资源“Menu”项中的IDR_MAINFRAME,利用菜单编辑器在“编辑”菜单的子菜单最后添加一个水平分隔符和一个“测试(&T)”菜单项(ID_EDIT_TEST)。为以后叙述方便,凡“XXXX”菜菜单单项项(ID_YY_YY)表示的菜单项是通过该菜单项属性对话框来设置的,且标题为XXXX,ID号为ID_YY_YY。本书作此约定! 4.2.2 工具按钮和菜单项相结合 由于按钮与菜单项命令一样,都可以通过MFC ClassWizard来直接映射,因此这里不再重复。这里就工具按钮和菜单项

44、相结合的问题来讨论一下。 工具按钮和菜单项相结合工具按钮和菜单项相结合就是指当选择工具按钮或菜单命令时,操作结果是一样的。实现的具体方法是在工具按钮的属性对话框中将按钮的ID号设置为相关联的菜单项ID。例如,下面的示例过程。陷遮蠢酿组串央貉呈企裳鲤控患史褥啄操矿弗政联醋婿覆送淘郴躬寡倍锋工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 (3)双击资源“Toolbar”项中的IDR_MAINFRAME,打开工具栏资源编辑器,为其添加并设计一个按钮,其位置和内容如图4.19所示。图图4.19 设计的工具栏按钮设计的工具栏按钮妇渡洼荡挂蛰尘挽夏蔡飘呈茧炕赦奏厢噪烂吨餐共仁拂旧袜舵乏逛殆厚朴工具栏和状态

45、栏工具栏和状态栏4.2工具栏工具栏 (4)双击刚才设计的第一个工具按钮,弹出该工具按钮的属性对话框,将该工具按钮的ID号设为ID_EDIT_TEST,在提示框内键入“工具栏按钮和菜单项命令相结合。n测试”。 (5)编译运行并测试。当程序运行后,将鼠标移至刚才设计的工具按钮处,这时在状态栏上显示出“工具栏按钮和菜单项命令相结合。”信息,若稍等片刻后,还会弹出提示小窗口,显示出“测试”字样。但此时的“测试”按钮和“测试”菜单项都是灰显,暂时无法操作它,这是因为程序中还没有任何与ID_EDIT_TEST命令相映射的消息处理函数。 (6)用MFC ClassWizard在CMainFrame添加ID_

46、EDIT_TEST的COMMAND消息映射,保留默认的消息处理函数名,添加下列代码: void CMainFrame:OnEditTest() MessageBox(测试命令已执行!); (7)再次编译运行并测试。牡哑砾壳赶扩贼洋翘猿挚痞酿柒苟汲逾势顷娜笨逻缉道痈巾彰浅赎诱库饵工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 4.2.3 多个工具栏的使用在用MFC AppWizard创建的文档应用程序中往往只有一个工具栏,但在实际应用中,常常需要多个工具栏。这里以一个实例的形式来讨论多个工具栏的创建、显示和隐藏等操作。 例例Ex_MultiBar 多个工具栏的使用多个工具栏的使用 (1)创建一个

47、默认的单文档应用程序Ex_MultiBar。 (2)将项目工作区切换到ResourceView页面,展开“Toolbar”(工具栏)资源,用鼠标单击IDR_MAINFRAME不松开,然后按下Ctrl键,移动鼠标将IDR_MAINFRAME拖到 Toolbar资源名称上,这样就复制了工具栏默认资源IDR_MAINFRAME,复制后的资源 标识系统自动设为IDR_MAINFRAME1。 (3)右击工具栏资源IDR_MAINFRAME1,从弹出的快捷菜单中选择Properties命令,如图4.20所示,将ID设为IDR_TOOLBAR1。图图4.20 工具栏属性对话框工具栏属性对话框返反干豁中盾音颓

48、潭小酉阂赐晚愈甭断芦赠刺忠疑根介蔽爷影斥诌崇送政工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 (4)双击IDR_TOOLBAR1,打开工具栏资源,删除几个“编辑”相关的工具按钮(目的是让IDR_TOOLBAR1工具栏与IDR_MAINFRAME有明显区别)。 (5)在CMainFrame类中添加一个成员变量m_wndTestBar,变量类型为CToolBar(CToolBar类封装了工具栏的操作)。 protected: / control bar embedded members CStatusBar m_wndStatusBar; CToolBar m_wndToolBar; CTool

49、Bar m_wndTestBar; (6)在CMainFrame:OnCreate函数中添加下面的工具栏创建代码: 分析和说明: 代码中,CreateEx是CToolBar类的成员函数,用来创建一个工具栏对象。该函数的第1个参数是用来指定工具栏所在的父窗口指针,this表示当前的CMainFrame类窗口指针。第2个参数用来指针工具按钮的风格,当为TBSTYLE_FLAT时表示工具按钮是“平面”的。第3个参数用来指针工具栏的风格。由于这里的工具栏是CMainFrame的子窗口,因此需要指定WS_CHILD | WS_VISIBLE。CBRS_TOP表示工具栏放置在父窗口的顶部,CBRS_GRI

50、PPER表示工具栏前面有一个“把手”,CBRS_TOOLTIPS表示允许有工具提示,CBRS_FLYBY表示在状态栏显示工具提示文本,CBRS_SIZE_DYNAMIC表示工具栏在浮动时,其大小是可以动态改变的。第4个参数是用来指定工具栏四周的边框大小,一般都为0。最后一个参数是用来指定工具栏这个子窗口的标识ID(与工具栏资源标识不同)。蚂妹儡蔫戳甭深急迭纹丑漫篱斗衣舷锐智曼救砖痹村箔决茹桃宰轿州煤早工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 if语句中的LoadToolBar函数是用来装载工具栏资源。若CreateEx或LoadToolBar的返回值为0,即调用不成功,则显示诊断信息“F

51、ailed to create toolbar”。TRACE0是一个用于程序调试的跟踪宏。OnCreate函数返回-1时,主框架窗口被清除。 应用程序中的工具栏一般具有停靠或浮动特性,m_wndTestBar.EnableDocking使得m_wndTestBar对象可以停靠,CBRS_ALIGN_ANY表示可以停靠在窗口的任一边。EnableDocking(CBRS_ALIGN_ANY)是调用的是CFrameWnd类的成员函数,用来让工具栏或其他控制条在主框架窗口可以进行停靠操作。DockControlBar也是CFrameWnd类的成员函数,用来将指定的工具栏或其他控制条进行停靠。 AFX

52、_IDW_TOOLBAR是系统内部的工具栏子窗口标识工具栏子窗口标识,并将AFX_IDW_TOOLBAR + 1的值表示默认的状态栏子窗口标识状态栏子窗口标识。如果在创建新的工具栏时没有指定相应的子窗口标识,则会使用默认的AFX_IDW_TOOLBAR。这样,当打开“查看”菜单时,单击“工具栏”菜单时,显示或隐藏的工具栏不是原来的工具栏而是新添加的工具栏。因此,需要重新指定工具栏子窗口的标识,并使其值等于AFX_IDW_TOOLBAR + 10。 朴伍阴摊攘俐痒亦挞御艇熄峙除扳这芳渍谆凰柑陈歹颓然仗葵拔袜刑彦调工具栏和状态栏工具栏和状态栏4.2工具栏工具栏(7)编译运行,结果如图4.21所示。

53、图图4.21 多个工具栏第一次运行的结果多个工具栏第一次运行的结果 (8)事实上多个工具栏的程序重点不是在于工具栏的显示,而是如何控制其显示。CFrameWnd:ShowControlBar函数就是起到这样的作用,有3个参数,第1个参数用来指定要操作的工具栏或状态栏指针,第2个参数是一个布尔型,当为TRUE时表示显示,否则表示隐藏,第3个参数用来表示是否延迟显示或隐藏,当为FALSE时表示立即显示或隐藏。冷性栈似褪秃兹枝蛇炬瓮挤盒丫庙韧桨漳闯每窃旺告媒髓寻酒儿勒簧僚憎工具栏和状态栏工具栏和状态栏4.2工具栏工具栏 (9)打开菜单资源IDR_MAINFRAME,在“查看”菜单下添加一个“新的工具

54、栏(&N)”菜单命令(ID_VIEW_NEWBAR)。 (10)用MFC ClassWizard在CMainFrame添加ID_VIEW_NEWBAR的COMMAND消息映射,保留默认的消息处理函数名,添加下列代码: void CMainFrame:OnViewNewbar() int bShow = m_wndTestBar.IsWindowVisible(); ShowControlBar( &m_wndTestBar, !bShow, FALSE); 代码中,IsWindowVisible 函数用来判断窗口(对象)是否可见。若为可见,则下句的ShowControlBar函数调用就使其隐藏

55、,反之就显示。 (11)编译运行并测试。 事实上,当ID_VIEW_NEWBAR工具栏显示时,还应使菜单“新的工具栏(&N)”文本前面能有一个显示,此时需跟踪交互对象的更新消息方可实现,后面会讨论这个问题。泻疹秘质筏洞兔耙耙儒咨带座钟豫映身碟相歇心捉果弗沛流尾章盯研惹沫工具栏和状态栏工具栏和状态栏4.3状态栏状态栏 4.3.1 状态栏的定义 用MFC AppWizard(.exe)创建的SDI或MDI应用程序框架中,有一个静态的indicator数组,它是在MainFrm.cpp文件中指定的,被MFC用作状态栏的定义。Static UINT indicators=ID_SEPARATOR,ID

56、_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,图图4.22 indicators数组的定义数组的定义耳趋抚屠绦遮藐摔哮氨塞潦与详呀门茵痘炕刑癌泛壕颐茧题懒某沫笔机萌工具栏和状态栏工具栏和状态栏4.3状态栏状态栏 4.3.2 状态栏的常用操作 Visual C+ 6.0中可以方便地对状态栏进行操作,如增减窗格、在状态栏中显示文本、改变状态栏的风格和大小等,并且MFC的CStatusBar类封装了状态栏的大部分操作。 1. 增加和减少窗格增加和减少窗格 状态栏中的窗格可以分为信息行窗格和指示器窗格两类。若在状态栏中增加一个信息行窗格,则只需在

57、indicators数组中的适当位置中增加一个ID_SEPARATOR标识即可;若在状态栏中增加一个用户指示器窗格,则在indicators数组中的适当位置增加一个在字符串表中定义过的资源ID,其字符串的长度表示用户指示器窗格的大小。若状态栏减少一个窗格,其操作与增加相类似,只需减少indicators数组元素即可。 2. 在状态栏上显示文本在状态栏上显示文本 调用CStatusBar:SetPaneText函数可以更新任何窗格(包括信息行窗格)中的文本。此函数原型描述如下: BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUp

58、date = TRUE ); 其中,lpszNewText表示要显示的字符串。nIndex是表示设置的窗格索引(第一个窗格的索引为0)。若bUpdate为TRUE,则系统自动更新显示的结果。 3. 示例示例 本示例用来将鼠标在窗口客户区的位置显示在状态栏上。坝诬绕市从兑伟分匀楼请孜近胃耗乏顷逛品西档求服撩炙鸟盟讯品驾汕瑰工具栏和状态栏工具栏和状态栏4.3状态栏状态栏 例例Ex_SDIMouse 在状态栏上显示鼠标位置在状态栏上显示鼠标位置 (1)创建一个默认的单文档应用程序Ex_SDIMouse。 (2)将项目工作区切换到ClassView页面,展开CMainFrame所有项,双击构造函数CM

59、ainFrame,在文档窗口中出现该函数的定义,在它的前面就是状态栏数组的定义。 (3)将状态栏indicators数组的定义改为下列代码: static UINT indicators = ID_SEPARATOR, ID_SEPARATOR, ; (4)由于鼠标移动消息WM_MOUSEMOVE在CMainFrame类映射后不起作用,因此只能映射到CEx_SDIMouseView类中。但是,这样一来,就需要更多的代码,因为状态栏对象m_wndStatusBar是在CMainFrame类定义的成员变量,因而需要在CEx_SDIMouseView类中添加访问CMainFrame类的代码。CEx_

60、SDIMouseView:OnMouseMove函数代码如下: 姜拯蕴班视幽釜嚼牌混铱飘症犊垣绘竹浓菜料琉氟扑疤渣捶此尧抨磅秽卧工具栏和状态栏工具栏和状态栏4.3状态栏状态栏void CEx_SDIMouseView:OnMouseMove(UINT nFlags, CPoint point) CString str; CMainFrame* pFrame=(CMainFrame*)AfxGetApp()-m_pMainWnd; / 获得主窗口指针 CStatusBar* pStatus=&pFrame-m_wndStatusBar; / 获得主窗口中的状态栏指针 if (pStatus) s

61、tr.Format(X=%d, Y=%d,point.x, point.y); / 格式化文本 pStatus-SetPaneText(1,str); / 更新第二个窗格的文本 CView:OnMouseMove(nFlags, point);喊缆品酣蛛劲帝窍走历挨妊孜呕猎烽齿伺边余蹋豢仇遇芬再喉诺鹏睛塔是工具栏和状态栏工具栏和状态栏4.3状态栏状态栏 代码中,AfxGetApp是CWinApp类的一个成员函数,该函数可在应用程序项目中的任何类中使用,用来获取应用程序中的CWinApp类对象指针。 (5)将MainFrm.h文件中的受保护变量m_wndStatusBar变成公共变量。 (6)在

62、Ex_SDIMouseView.cpp文件的开始处增加下列语句: #include Ex_SDIMouseView.h #include MainFrm.h (7)编译并运行,结果如图4.23所示。图图4.23 鼠标的位置显示在状态栏上鼠标的位置显示在状态栏上茸障沾驴墟过徒喇绍出少暮惩询硷走爵萄云坐藏弦普梅露力早巍尺克炯褒工具栏和状态栏工具栏和状态栏4.3状态栏状态栏 4.33 改变状态栏的风格 在MFC的CStatusBar类中,有两个成员函数可以改变状态栏风格,它们是: void SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxW

63、idth ); void SetPaneStyle( int nIndex, UINT nStyle ); 其中,参数nIndex表示要设置的状态栏窗格的索引,nID用来为状态栏窗格指定新的ID,cxWidth表示窗格的像素宽度,nStyle表示窗格的风格类型,用来指定窗格的外观,例如SBPS_POPOUT表示窗格是凸起来的,具体见表4.6。表表4.6 状态栏窗格的风格类型状态栏窗格的风格类型风格类型风格类型含含 义义SBPS_NOBORDERS窗格周围没有3D边框SBPS_POPOUT反显边界以使文字“凸出来”SBPS_DISABLED禁用窗格,不显示文本SBPS_STRETCH拉伸窗格,并

64、填充窗格不用的空白空间。但状态栏只能有一个窗格具有这种风格SBPS_NORMAL普通风格,它没有“拉伸”,“3D边框”或“凸出来”等特性斡锐泅苟诗靴悬逃鬃栓亏雄淬粮仔申旗危遮收撞漓凿藩振骆腮丘妄腕曼宫工具栏和状态栏工具栏和状态栏4.3状态栏状态栏例如,在前面的示例中,将OnMouseMove函数修改为下列代码,则结果如图4.24所示。 void CEx_SDIMouseView:OnMouseMove(UINT nFlags, CPoint point) CString str;CMainFrame* pFrame=(CMainFrame*)AfxGetApp()-m_pMainWnd; /

65、获得主窗口指针CStatusBar* pStatus=&pFrame-m_wndStatusBar; / 获得主窗口中的状态栏指针if (pStatus) pStatus-SetPaneStyle(1, SBPS_POPOUT); str.Format(X=%d, Y=%d,point.x, point.y); / 格式化文本 pStatus-SetPaneText(1,str); / 更新第二个窗格的文本 CView:OnMouseMove(nFlags, point); 图图4.24 设置状态栏的风格设置状态栏的风格氓谩羔悄脂吵摹膛牧籍掺钝各畸议储只简共庸酣衔遗藉宦粳施藏域辖寇牟工具栏和状

66、态栏工具栏和状态栏4.4交互对象的动态更新交互对象的动态更新 为了能使用户交互对象动态更新,MFC通过ClassWizard直接映射交互对象的更新命令消息来实现的。它自动将用户交互对象的ID标识符与ON_UPDATE_COMMAND_UI宏相连接并产生处理更新消息的相应函数。例如,打开Ex_MultiBar应用程序,用MFC ClassWizard在CMainFrame类中添加菜单ID_VIEW_NEWBAR的UPDATE_COMMAND_UI消息映射,保留其默认的映射函数名,并添加下列代码: void CMainFrame:OnUpdateViewNewbar(CCmdUI* pCmdUI)

67、 int bShow = m_wndTestBar.IsWindowVisible(); pCmdUI -SetCheck( bShow ); 代码中,OnUpdateViewNewbar是ID_VIEW_NEWBAR的更新命令消息的消息映射函数。该函数只有一个参数,它是指向CCmdUI对象的指针。CCmdUI 类仅用于ON_UPDATE_COMMAND_UI消息映射函数,它的成员函数将对菜单项、工具按钮等用户交互对象起作用,具体如表4.7所示。编译运行并测试。打开“查看”菜单,可以看到“新的工具栏(&N)”菜单前面有一个“”,再次选择“新的工具栏(&N)”菜单,则新创建的工具栏不见,“新的工

68、具栏(&N)”菜单前面没有任何标记。若将代码中的SetCheck改为SetRadio,则“”变成了“”,这就是交互对象的更新效果。抱苟损犊陇育粹物钦搜例襟瑰茁控臆瀑玛东鄙筏受抚貌雏填帧膝土柞谊阵工具栏和状态栏工具栏和状态栏4.4交互对象的动态更新交互对象的动态更新表表4.7 CCmdUI 类的成员函数对用户交互对象的作用类的成员函数对用户交互对象的作用选中(用户交互对象EnableSetCheckSetRadioSetText菜单项允许或禁用 )或未选中选中用点()设置菜单文本工具栏按钮允许或禁用选定、未选定或不确定同SetCheck无效状态栏窗格(PANE)使文本可见或不可见边框外凸或正常同

69、SetCheck设置窗格文本CDialogBar中的按钮允许或禁用选中或未选中同SetCheck设置按钮文本CDialogBar中的控件允许或禁用无效无效设置窗口文本陡老过侍母济姐拾轨簧谣酥星岔椽魄搓蔓漱斋桓笺饲蹋孙抬男艾起曙振饺工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 为了能对学生成绩记录进行管理,常见的操作包括:添加、删除和查找等。 这些操作在在文档应用程序中实现时可以有多种界面方法,具体如下: (1)构造单独的“操作”工具栏,包含上述操作的工具按钮。 (2)在文档应用程序的主菜单中的“查看”菜单下添加一个“操作工具栏(&O)”菜单命令,用来控制“操作”工具栏的显示。 (3)当“

70、操作”工具栏显示时,“操作工具栏(&O)”菜单命令前面有一个“”,且在 “帮助”菜单项前面出现“操作(&O)”菜单项,包含用于添加、删除和查找的各个子菜单项。 (4)当“操作”工具栏隐藏时,“操作(&O)”菜单项消失,且“操作工具栏(&O)”菜单命令前面没有任何标记。用快捷键Ctrl+1关联“操作工具栏(&O)”菜单命令。 (5)单击操作工具栏的“添加”按钮或选择“操作”菜单中的“添加”命令,弹出“学生成绩”对话框,单击确定按钮,学生成绩记录显示在状态栏上。结果如图4.25所示。琐涸逛母野帝忘忧耍祷啃在瘟快极飞怎伴侗消教咐九抠止吊艇北稗熙解真工具栏和状态栏工具栏和状态栏4.5综合应用综合应用图

71、图4.25 综合应用题图综合应用题图 具体实现步骤如下(分四步阐述:设计学生成绩对话框、设计“操作”工具栏和菜单、添加联动代码、修改状态栏完善代码): 例例Ex_A4 第四章综合应用第四章综合应用 1)设计学生成绩对话框)设计学生成绩对话框奏田肢貉贡主恢古株薛只田茵闲吏邵磐巨收神棕试传由琅赵因毋绑肢借戳工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (1)用MFC AppWizard(exe)创建一个默认的单文档应用程序Ex_A4。 (2)添加一个新的对话框资源,通过其属性对话框,将ID标识符改为IDD_SCORE,标题为“学生成绩”,将对话框字体改为“宋体,9号”。 (3)显示对话框网格

72、,调整对话框的大小,向对话框添加如表3.7所示的控件,调整控件的位置,结果如图4.26所示。图图4.26 设计的学生成绩对话框设计的学生成绩对话框表表4.8 学生成绩对话框添加的控件学生成绩对话框添加的控件添加的控件添加的控件ID标识符标识符标标 题题其他属性其他属性编辑框IDC_EDIT_NAME默认编辑框IDC_EDIT_NO默认编辑框IDC_EDIT_S1默认编辑框IDC_EDIT_S2默认编辑框IDC_EDIT_S3默认趴宽纲膛叠猜券顽樟储蜘芜梯呻怯姆媒瓣艇胳嗽莉星绸兜二湿克其粗主胸工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (4)双击对话框模板空白处,为该对话框模板创建一个对

73、话框类CScoreDlg。 (5)在MFC ClassWizard的Member Variables页面中,确定Class name中是否已选择了CScoreDlg,选中所需的控件ID标识符,双击鼠标或单击Add Variables按钮。依次为表4.9控件增加成员变量。表表4.9 控件变量控件变量控件控件ID标识符标识符变量类别变量类别变量类型变量类型变量名变量名范围和大小范围和大小IDC_EDIT_NAMEValueCStringm_strName20IDC_EDIT_NOValueCStringm_strNO20IDC_EDIT_S1Valuefloatm_fScore10.0 100.0

74、IDC_EDIT_S2Valuefloatm_fScore20.0 100.0IDC_EDIT_S3Valuefloatm_fScore30.0 100.0马揖碟绑醇狡琐鸭齐擅恳桥灾涪州诣晚傀崎檀富衣牺无翼隘荷根固乐汀酝工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 2)设计)设计“操作操作”工具栏和菜单工具栏和菜单 (1)按Ctrl+R快捷键,在“插入资源”对话框中,选中“Toolbar”类型,单击新建按钮,这样就会为应用程序添加一个工具栏资源,并自动打开相应的编辑器,且第一次添加的默认ID为IDR_TOOLBAR1。 (2)按图4.27所示,用工具栏资源编辑器为IDR_TOOLBAR1

75、添加3个按钮,其ID号依次设为:ID_OP_ADD、ID_OP_DEL和ID_OP_SEEK。图图4.27 工具栏设计工具栏设计林黍鸟碗成订识撒现诞赦镁撬惟经么九猿仅耽炒诧含弧严习谊焰沉害齿六工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (3)在CMainFrame类中添加一个成员变量m_wndOpBar,变量类型为CToolBar。 (4)在CMainFrame:OnCreate函数中添加下面的工具栏创建代码: (5)按Ctrl+R快捷键,在“插入资源”对话框中,选中“Menu”类型,单击新建按钮,这样就会为应用程序添加一个菜单资源,并自动打开相应的编辑器,且第一次添加的默认ID为ID

76、R_MENU1。 (6)添加“操作”顶层下拉菜单,其子菜单依次为“添加(&A)”(ID_OP_ADD)、“删除(&D)”(ID_OP_DEL)和“查找(&K)”(ID_OP_SEEK)。 (7)在ResourceView页面中,双击资源“Menu”中的IDR_MAINFRAME,在“查看”菜单的最后添加一个菜单命令项“操作工具栏(&O)tCtrl+1”(ID_VIEW_OP)。 3)添加联动代码)添加联动代码 (1)在项目工作区窗口的ResourceView(资源视图)页面中,展开中Accelerator(加速键)的资源项,双击IDR_MAINFRAME。在右侧窗口中出现如图4.7的加速键资源

77、列表。 (2)双击加速键列表的最下端的空行,在弹出的“Accel 属性”(Accel Properties)对话框 中 将ID号选为ID_VIEW_OP,然后单击下一键按钮,并按下Ctrl+1作为此加速键的键值。关闭“Accel 属性”对话框。蛀秃既囚拉彩奢蓖堕候揪截票待扫丈苇泳竣巳贼湾膛瓷缄泳恐禽犬汰钾沽工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (3)为CMainFrame类添加一个CMenu类的成员变量m_popMenu,以及一个成员函数UpdateOpMenu,代码如下: (4)按Ctrl+W键打开MFC ClassWizard对话框,切换到Message Maps页面,在CM

78、ainFrame类中添加ID_VIEW_OP命令的COMMAND和UPDATE_COMMAND_UI消息映射,保留默认的映射函数名,添加下列代码: void CMainFrame:OnViewOp() int bShow = m_wndOpBar.IsWindowVisible(); ShowControlBar( &m_wndOpBar, !bShow, FALSE); UpdateOpMenu( !bShow ); void CMainFrame:OnUpdateViewOp(CCmdUI* pCmdUI) int bShow = m_wndOpBar.IsWindowVisible();

79、 pCmdUI -SetCheck( bShow ); 粉氏武朝筹滞芹野侧笋粉贝欧谈徽纯善农哇守随拐全猖涸曹云吨翘忠帮乙工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (5)修改CMainFrame:OnCreate中的后面代码: int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) m_wndOpBar.SetWindowText(操作); m_popMenu.LoadMenu( IDR_MENU1 ); UpdateOpMenu( TRUE ); return 0; (6)编译运行并测试。此时会发现工具栏、菜单项和快捷键的联动功能

80、已实现,但“操作”菜单项和工具按钮都是灰显的,这是因为还没有对这些命令进行映射。 4)修改状态栏,完善代码)修改状态栏,完善代码 (1)将项目工作区切换到ClassView页面,展开CMainFrame所有项,双击构造函数CMainFrame,在文档窗口中出现该函数的定义,在它的前面就是状态栏数组的定义。 (2)将状态栏indicators数组的定义改为下列代码: static UINT indicators = ID_SEPARATOR, ID_SEPARATOR, ;蛙巡酬潦癌妒肯巧躲卒猛栏果墓虱乞愉悬霍晕窜阮广珐已窘要惫缸宅槐误工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (3)按

81、Ctrl+W键打开MFC ClassWizard对话框,切换到Message Maps页面,在CMainFrame类中分别添加ID_OP_ADD、ID_OP_DEL和ID_OP_SEEK 的COMMAND消息映射,保留默认的映射函数名。其中,仅对OnOpAdd添加下列代码(因为其他2个命令的映射仅使相应的菜单命令项和工具按钮有效): void CMainFrame:OnOpAdd() CScoreDlg dlg; if (IDOK = dlg.DoModal() ) / 当输入记录有效后,获取相关记录,然后在状态上显示出来CString strRes;strRes.Format( 姓名:%s,

82、 学号:%s, 3门成绩: %.1f, %0.1f, %.1f, dlg.m_strName, dlg.m_strNO, dlg.m_fScore1, dlg.m_fScore2, dlg.m_fScore3 );m_wndStatusBar.SetPaneText( 1, strRes ); elsem_wndStatusBar.SetPaneText( 1, 无有效的学生成绩记录! ); 募七售祷邢神炎耙吻慨瞎瓣苏毋贞给溢践笛栏咖穆虏儡魄掘羡掣魂转沂剑工具栏和状态栏工具栏和状态栏4.5综合应用综合应用 (4)在MainFrm.cpp文件的前面添加CScoreDlg类的头文件包含: #inc

83、lude MainFrm.h #include ScoreDlg.h (5)编译运行并测试。 总之,菜单命令(包括快捷菜单)、工具栏上的按钮以及快捷键是构成文档应用程序框架的最基本命令系统,而提示文本、交互对象更新状态和状态栏等是构成文档应用程序框架的最基本信息系统,这些都是属于文档应用程序框架的界面问题。事实上,文档应用程序的界面设计中还有图标、光标以及框架窗口的样式设置等一系列问题,下一章就来讨论。讳砖害扛桩毋无轿惮涤亮斗师拭啪岿屯叉肪狙豹役遗蜜列宙柬蛆歧恋竣袜工具栏和状态栏工具栏和状态栏 习题习题 1. 菜单有哪些常见的规则?什么是助记符?它是如何在菜单中定义的? 2. 菜单项的消息有哪

84、些?若对同一个菜单用ClassWizard分别在视图类和主框架窗口类CMainFrame都处理其COMMAND消息,并在它们的函数中添加相同的代码,则当用户选择该菜单后,会有什么样的结果?为什么? 3. 如何对已有的菜单中添加一个菜单项、一个弹出菜单? 4. 什么是键盘快捷键?它是如何定义的? 5. 什么是快捷菜单?快捷菜单能否通过映射右击鼠标消息来实现,为什么? 6. 如何使一个工具按钮和某菜单项命令相结合?如何显示和隐藏一个工具栏?如何设置工具栏的标题? 7. 状态栏的作用是什么?状态栏的窗格分为几类?如何添加和减少相应的窗格? 8. 若状态栏只有一个用户定义的指示器窗格(其ID号为ID_TEXT_PANE),应如何定义?若当用户在客户区双击鼠标时,在该窗格中显示“双击鼠标”字样,则应如何编程? 9. 什么是命令更新消息?它的作用是什么?物缀秦伙污睦乱抗皮寓巨慎蝇肥耶储砍尧来瘪脯邹脊拢静陕炽极乏劳鲤众工具栏和状态栏工具栏和状态栏

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号