第06章 菜单、工具栏和状态栏.ppt
第第6章菜单、工具栏和状态栏章菜单、工具栏和状态栏 6.1 菜单菜单 6.2 工具栏工具栏 6.3 状态栏状态栏 6.4 交互对象的动态更新交互对象的动态更新作业作业 6.1菜单菜单 对于菜单的显示都遵循下列一些规则:对于菜单的显示都遵循下列一些规则:u若点击某菜单项会弹出一对话框,那若点击某菜单项会弹出一对话框,那么在该菜单项文本后有么在该菜单项文本后有“”。u若某项菜单有子菜单,那么在该菜单若某项菜单有子菜单,那么在该菜单项文本后有项文本后有“”。u菜单项需要助记符,用括号将带下划菜单项需要助记符,用括号将带下划线的字母括起来。助记符与线的字母括起来。助记符与Alt构成构成一个组合键,当按住一个组合键,当按住“Alt”键不放,键不放,再敲击该字母时,对应的菜单项就会再敲击该字母时,对应的菜单项就会被选中。被选中。u若某项菜单需要快捷键的支持,则一若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。任般将其列在相应菜单项文本之后。任何时候按下快捷键,相应的菜单命令何时候按下快捷键,相应的菜单命令都会被执行。都会被执行。图图6.1 File菜单菜单6.1菜单菜单6.1.1用编辑器设计菜单用编辑器设计菜单 编辑菜单编辑菜单 在菜单的空位置上双击鼠标左键,则出现它的属性对话框,如图。在菜单的空位置上双击鼠标左键,则出现它的属性对话框,如图。图图6.2 菜单编辑器菜单编辑器菜单的空位置6.1菜单菜单图图6.3 菜单属性对话框菜单属性对话框6.1菜单菜单需要注意的是:需要注意的是:u当菜单项的属性中选中了当菜单项的属性中选中了Pop_up时,对话框中时,对话框中ID、Separator和和Prompt项无效。项无效。u增加新的菜单项后,用户可以用鼠标将菜单项拖到其他位置,而当菜单项位增加新的菜单项后,用户可以用鼠标将菜单项拖到其他位置,而当菜单项位置改变时,其属性并没改变。置改变时,其属性并没改变。菜单项被拖动的位置图图6.4 拖动菜单项拖动菜单项图图6.5 添加的菜单项添加的菜单项6.1菜单菜单菜单命令的消息映射菜单命令的消息映射 例例Ex_Mmenu“成绩输入成绩输入”菜单项的映射。菜单项的映射。(1)选选择择“View”菜单菜单“ClassWizard”命令项或按命令项或按Ctrl+w快捷键,则出现快捷键,则出现MFC ClassWizard对话框,切换到对话框,切换到Message Maps页面。页面。(2)从从“Class name”列表中选择列表中选择CMainFrame,在,在IDs列表中选择列表中选择ID_SCORE_IN,然后在然后在Messages框中选择框中选择COMMAND消息,如图。消息,如图。图图6.6 消息的选择消息的选择6.1菜单菜单(3)单击单击Add Function按钮或双击按钮或双击COMMAND消息,输入成员函数的名消息,输入成员函数的名称。如图。称。如图。(4)单击单击OK。选择新增加的成员函数,单击选择新增加的成员函数,单击Edit Code按钮按钮(或直接在函或直接在函数名双击鼠标左键数名双击鼠标左键),就可以在此成员函数中添加一些代码。例如:,就可以在此成员函数中添加一些代码。例如:void CMainFrame:OnScoreIn()/TODO:Add your command handler code hereAfxMessageBox(现在就输入成绩吗?现在就输入成绩吗?);(5)编译并运行。在应用程序的顶层菜单上,单击编译并运行。在应用程序的顶层菜单上,单击“成绩输入成绩输入”菜单项或按菜单项或按Alt+S组合键,如图。组合键,如图。图图6.7 添加成员函数对话框添加成员函数对话框图图6.8 菜单命令执行的结果菜单命令执行的结果6.1菜单菜单6.1.2使用键盘快捷键使用键盘快捷键(1)先打开上例的项目工作区窗口中先打开上例的项目工作区窗口中Accelerator的资源项,双击的资源项,双击IDR_MAINFRAME,如图。如图。图图6.9 示例示例Ex_Sdi的加速键资源的加速键资源最下端的空行6.1菜单菜单(2)要建立一新的加速键,双击加速键列表的最下端的空行,如图,其中可要建立一新的加速键,双击加速键列表的最下端的空行,如图,其中可设置的属性如表设置的属性如表(3)在上述对话框中,选择在在上述对话框中,选择在Ex_Sdi示例中添加的示例中添加的“成绩输入成绩输入”菜单项的菜单项的ID号号ID_SCORE_IN作为要联用的加速键的作为要联用的加速键的ID号,单击号,单击Next Key Typed,按下按下Ctrl+1作为此加速键的键值。作为此加速键的键值。图图6.10 “Accel Properities”对话框对话框6.1菜单菜单6.1.3菜单的编程控制菜单的编程控制 菜单的基本操作菜单的基本操作(1)创建菜单创建菜单CMenu类的类的CreateMenu和和CreatePopupMenu用来创建一个菜单或子菜单框架,用来创建一个菜单或子菜单框架,原型如下:原型如下:BOOL CreateMenu();/产生一个空菜单产生一个空菜单BOOL CreatePopupMenu();/产生一个空的弹出式子菜单产生一个空的弹出式子菜单(2)装入菜单装入菜单将菜单从资源装入应用程序中,需调用将菜单从资源装入应用程序中,需调用CMenu成员函数成员函数LoadMenu,或者用或者用SetMenu对应用程序菜单进行重新设置。对应用程序菜单进行重新设置。BOOL LoadMenu(LPCTSTR lpszResourceName);BOOL LoadMenu(UINT nIDResource);(3)添加菜单项添加菜单项菜单创建后,可调用菜单创建后,可调用AppendMenu或或InsertMenu函数添加一些菜单项。函数添加一些菜单项。AppendMenu是将菜单项添加在菜单的末尾处,是将菜单项添加在菜单的末尾处,InsertMenu在菜单的指定位置处在菜单的指定位置处插入菜单项,并将后面的菜单项依次下移。插入菜单项,并将后面的菜单项依次下移。BOOL AppendMenu(UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL);BOOL AppendMenu(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);6.1菜单菜单需要注意的是:需要注意的是:unFlags为为MF_BYPOSITION时,时,nPosition表示新菜单项要插入的具体位表示新菜单项要插入的具体位置,为置,为0时表示第一个菜单项,为时表示第一个菜单项,为-1时,将菜单项添加菜单的末尾处。时,将菜单项添加菜单的末尾处。unFlags的标志中,可以用的标志中,可以用“|”(按位或按位或)来组合,例如来组合,例如MF_CHECKED|MF_STRING等。有些组合是不允许的,例如等。有些组合是不允许的,例如MF_DISABLED、MF_ENABLED和和MF_GRAYED,MF_STRING、MF_OWNERDRAW、MF_SEPARATOR和位图,和位图,MF_CHECKED和和MF_UNCHECKED 都不能组合在一起。都不能组合在一起。u当菜单项增加后,不管菜单依附的窗口是否改变,都应调用当菜单项增加后,不管菜单依附的窗口是否改变,都应调用CWnd:DrawMenuBar来更新菜单。来更新菜单。6.1菜单菜单(4)删除菜单项删除菜单项调用调用DeleteMenu函数可将指定的菜单项删除,需要注意的是:调用该函函数可将指定的菜单项删除,需要注意的是:调用该函数后,不管菜单依附的窗口是否改变,都应调用数后,不管菜单依附的窗口是否改变,都应调用CWnd:DrawMenuBar使使菜单更新。函数菜单更新。函数DeleteMenu的原型如下:的原型如下:BOOL DeleteMenu(UINT nPosition,UINT nFlags);nPosition表示要删除的菜单项位置,它由表示要删除的菜单项位置,它由nFlags进行说明。若当进行说明。若当nFlags为为MF_BYCOMMAND时,时,nPosition表示菜单项的表示菜单项的ID号,而当号,而当nFlags为为MF_BYPOSITION时,时,nPosition表示菜单项的位置表示菜单项的位置(第一个菜单项位置为第一个菜单项位置为0)。(5)获取菜单项获取菜单项下面的三个下面的三个CMenu成员函数分别获得菜单的项数、菜单项的成员函数分别获得菜单的项数、菜单项的ID号以及弹出号以及弹出式子菜单的句柄。式子菜单的句柄。UINT GetMenuItemCount()const;该函数用来获得菜单的菜单项数,调用失败后返回该函数用来获得菜单的菜单项数,调用失败后返回-1。UINT GetMenuItemID(int nPos)const;该函数用来获得由该函数用来获得由nPos指定菜单项位置指定菜单项位置(以以0为基数为基数)的菜单项的标识号,的菜单项的标识号,若若nPos是是SEPARATOR,则返回则返回-1。CMenu*GetSubMenu(int nPos)const;该函数获得指定菜单的弹出式菜单的菜单句柄。该弹出式菜单位置由参数该函数获得指定菜单的弹出式菜单的菜单句柄。该弹出式菜单位置由参数nPos指定,开始的位置为指定,开始的位置为0。若菜单不存在,则创建一个临时的菜单指针。若菜单不存在,则创建一个临时的菜单指针。6.1菜单菜单给系统菜单添加一个菜单项给系统菜单添加一个菜单项例例Ex_SysMenu 向应用系统菜单中添加一个菜单项。向应用系统菜单中添加一个菜单项。(1)打开一个单文档应用程序项目,若没有可按前面提及的方法进行创建。打开一个单文档应用程序项目,若没有可按前面提及的方法进行创建。(2)选择选择“View”菜单菜单“Resource Symbols”命令,如图。命令,如图。(3)单击单击New,如图。在如图。在Name框中,可以指定一个用于菜单项的框中,可以指定一个用于菜单项的ID号。号。在在Value框中,可以定义该框中,可以定义该ID的值,系统要求定义的的值,系统要求定义的ID值应大于值应大于15(0X000F)而小于而小于61440(0XF000)。选择默认的选择默认的ID值值101,单击,单击OK按钮。按钮。图图6.11 “Resource Symbols”对话框对话框图图6.12 “New Symbol”对话框对话框6.1菜单菜单(4)在在CMainFrame:OnCreate函数体函数体(或自定义的函数或自定义的函数)中加入代码:中加入代码: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,StrMenuItem);/允许使用允许使用ON_UPDATE_COMMAND_UI或或ON_COMMAND的菜单项的菜单项m_bAutoMenuEnable=FALSE;/使添加的菜单处于允许状态,默认为使添加的菜单处于允许状态,默认为灰显灰显 pSysMenu-EnableMenuItem(ID_NEW_MENUITEM,MF_BYCOMMAND|MF_ENABLED);DrawMenuBar();/更新菜单更新菜单return 0;(5)使用使用ClassWizard处理处理OnCommand消息并检测用户菜单的消息并检测用户菜单的nID参数。参数。BOOL CMainFrame:OnCommand(WPARAM wParam,LPARAM lParam)/wParam的低字节表示菜单、控件、加速键的命令的低字节表示菜单、控件、加速键的命令ID if(LOWORD(wParam)=ID_NEW_MENUITEM)MessageBox(你选中了新的菜单项你选中了新的菜单项);return CFrameWnd:OnCommand(wParam,lParam);(6)编译运行并测试。编译运行并测试。6.1菜单菜单6.1.4使用快捷菜单使用快捷菜单 用资源编辑器和用资源编辑器和MFC库的库的CMenu:TrackPopupMenu函数创建这函数创建这样的菜单,样的菜单,CMenu:TrackPopupMenu函数原型如下:函数原型如下:BOOL TrackPopupMenu(UINT nFlags,int x,int y,CWnd*pWnd,LPCRECT lpRect=NULL);x和和y表示菜单的水平坐标和菜单的顶端的垂直坐标。表示菜单的水平坐标和菜单的顶端的垂直坐标。pWnd表示弹表示弹出菜单的窗口。出菜单的窗口。lpRect是一个是一个RECT结构或结构或CRect对象指针,表示一对象指针,表示一个矩形区域,单击这个区域时,弹出菜单不消失。当个矩形区域,单击这个区域时,弹出菜单不消失。当lpRect为为NULL时,若击在菜单外面,菜单立刻消失。时,若击在菜单外面,菜单立刻消失。6.1菜单菜单例例Ex_Menu创建弹出菜单。创建弹出菜单。(1)选择选择“Insert”菜单菜单“Resource”命令或按命令或按Ctrl+R快捷键,向应用快捷键,向应用程序项目添加一个新的菜单资源程序项目添加一个新的菜单资源(默认的默认的ID号为号为 IDR_MENU1)。(2)用菜单编辑器,为该菜单资源中的顶层菜单的第一项加一任意标题用菜单编辑器,为该菜单资源中的顶层菜单的第一项加一任意标题(实际上该标题无用实际上该标题无用),在此菜单项下依次添加如下表所示的菜单项。,在此菜单项下依次添加如下表所示的菜单项。(3)将此菜单资源将此菜单资源ID号改为号改为IDR_MYFLOATMENU。(4)按按Ctrl+W快捷键打开快捷键打开ClassWizard,将出现一对话框,询问是将出现一对话框,询问是“选择一个已存在的类选择一个已存在的类”,还是,还是“创建一个新类创建一个新类”。选择。选择“选择一个选择一个已存在的类已存在的类”项并选定项并选定CMainFrame类。类。6.1菜单菜单(5)在在CMainFrame类中,选择上表中所列的菜单类中,选择上表中所列的菜单ID,双击双击COMMAND消息。消息。这是仅为菜单这是仅为菜单ID_MENU_SCOREIN映射映射COMMAND消息,添加代码:消息,添加代码:void CMainFrame:OnMenuScorein()AfxMessageBox(现在就输入成绩吗?现在就输入成绩吗?);(6)在在CMainFrame类加入类加入WM_CONTEXTMENU消息处理函数,代码。消息处理函数,代码。void CMainFrame:OnContextMenu(CWnd*pWnd,CPoint point)CMenu menu;menu.LoadMenu(IDR_MYFLOATMENU);menu.GetSubMenu(0)-TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);(7)运行并测试。在应用程序的窗口客户区中单击鼠标右键,弹出如图菜单。运行并测试。在应用程序的窗口客户区中单击鼠标右键,弹出如图菜单。“成绩打印成绩打印”菜单命令没有消息处理函数,因此它是灰显的,用户不能使用它菜单命令没有消息处理函数,因此它是灰显的,用户不能使用它们。若用户选中们。若用户选中“成绩输入成绩输入”菜单命令,则会执行相应的代码。菜单命令,则会执行相应的代码。图图6.13 快捷菜单快捷菜单6.2工具栏工具栏 6.2.1使用工具栏编辑器使用工具栏编辑器 选择选择“File”“Open Workspace”,将单文档应用程序将单文档应用程序Ex_Sdi调入或重调入或重新创建。在项目工作区窗口中选择新创建。在项目工作区窗口中选择ResourceView标签,双击标签,双击“Toolbar”项中的项中的IDR_MAINFRAME,则工具栏编辑器出现在主界面的右边,如图。则工具栏编辑器出现在主界面的右边,如图。图图6.14 工具栏编辑器窗口工具栏编辑器窗口空按钮6.2工具栏工具栏(1)创建一个新的工具栏按钮创建一个新的工具栏按钮在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在在ID框中输入其标识符名称,则在其右端又出现一个新的空按钮。单击该按框中输入其标识符名称,则在其右端又出现一个新的空按钮。单击该按钮,在编辑器的视窗内进行编辑,这个编辑就是绘制一个按钮位图。钮,在编辑器的视窗内进行编辑,这个编辑就是绘制一个按钮位图。(2)移动一个按钮移动一个按钮在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相应位置即可。如果在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相应位置即可。如果用户拖动它离开工具栏位置,则此按钮从工具栏中消失。若在移动一个按钮用户拖动它离开工具栏位置,则此按钮从工具栏中消失。若在移动一个按钮的同时,按下的同时,按下Ctrl键,则在新位置复制一个按钮,新位置可以是同一个工具栏键,则在新位置复制一个按钮,新位置可以是同一个工具栏中的其他位置,也可以在不同的工具栏中。中的其他位置,也可以在不同的工具栏中。(3)删除一个按钮删除一个按钮前面已提到过,将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中前面已提到过,将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中按钮后,单击按钮后,单击Delete键并不能删除一个按钮,只是将按钮中的图形全部以背键并不能删除一个按钮,只是将按钮中的图形全部以背景色填充。景色填充。(4)在工具栏中插入空格在工具栏中插入空格u如果按钮前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上如果按钮前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。时,释放鼠标键,则此按钮前出现空格。u如果按钮前有空格而按钮后没有空格,拖动该按钮向左移动并当按钮的左边界如果按钮前有空格而按钮后没有空格,拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。u如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。6.2工具栏工具栏(5)工具栏按钮属性的设置工具栏按钮属性的设置双击某按钮弹出其属性对话框,如图。双击某按钮弹出其属性对话框,如图。图图6.15 工具栏按钮属性对话框工具栏按钮属性对话框6.2工具栏工具栏6.2.2工具栏和菜单相结合工具栏和菜单相结合 例例Ex_T&M 将菜单项将菜单项ID_SCORE_IN与工具按钮相结合。与工具按钮相结合。(1)将前面的单文档应用程序将前面的单文档应用程序Ex_Sdi打开;打开;(2)利用工具栏编辑器设计一个工具按钮,如图;利用工具栏编辑器设计一个工具按钮,如图;(3)双击刚才设计的工具按钮图形,弹出该工具按钮的属性对话框;双击刚才设计的工具按钮图形,弹出该工具按钮的属性对话框;(4)在工具按钮的属性对话框中,将工具按钮的在工具按钮的属性对话框中,将工具按钮的ID号设为号设为ID_SCORE_IN,在,在Prompt框内键入框内键入“向系统输入学生成绩向系统输入学生成绩n成绩输入成绩输入”;(5)重新编译并运行程序。在重新编译并运行程序。在Ex_Sdi工具栏上,将鼠标指针移至刚才设计的工具按钮工具栏上,将鼠标指针移至刚才设计的工具按钮处,这时在状态栏上显示出处,这时在状态栏上显示出“向系统输入学生成绩向系统输入学生成绩”信息,若稍等片刻后,还会弹信息,若稍等片刻后,还会弹出提示小窗口,显示出出提示小窗口,显示出“成绩输入成绩输入”字样。字样。图图6.16 工具栏按钮的设计工具栏按钮的设计6.3状态栏状态栏 6.3.1状态栏的定义状态栏的定义 用用AppWizard创建的创建的SDI或或MDI应用程序框架中,有一个静态的应用程序框架中,有一个静态的indicator数组,它是在数组,它是在MainFrm.cpp文件中定义的,被文件中定义的,被MFC用作状态栏的定义。用作状态栏的定义。Static UINT indicators=ID_SEPARATOR,ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,图图6.17 indicators数组的定义数组的定义6.3状态栏状态栏6.3.2状态栏的常用操作状态栏的常用操作增加和减少窗格增加和减少窗格状态栏中的窗格可以分为信息行窗格和指示器窗格两类。若在状态栏中增状态栏中的窗格可以分为信息行窗格和指示器窗格两类。若在状态栏中增加一个信息行窗格,则只需在加一个信息行窗格,则只需在indicators数组中的适当位置中增加一个数组中的适当位置中增加一个ID_SEPARATOR标识;若在状态栏中增加一个用户指示器窗格,则在标识;若在状态栏中增加一个用户指示器窗格,则在indicators数组中的适当位置增加一个在字符串表中定义过的资源数组中的适当位置增加一个在字符串表中定义过的资源ID,其其字符串的长度表示用户指示器窗格的大小。若状态栏减少一个窗格,其操字符串的长度表示用户指示器窗格的大小。若状态栏减少一个窗格,其操作与增加相类似,只需减少作与增加相类似,只需减少indicators数组元素。数组元素。在状态栏上显示文本在状态栏上显示文本有三种办法可以在状态栏窗格显示文本信息:有三种办法可以在状态栏窗格显示文本信息:(1)调用调用CWnd:SetWindowText更新信息行窗格更新信息行窗格(或窗格或窗格0)中的文本。由中的文本。由于状态栏也是一种窗口,故在使用时可直接调用。若状态栏变量为于状态栏也是一种窗口,故在使用时可直接调用。若状态栏变量为m_wndStatusBar,则,则m_wndStatusBar.SetWindowText(“消息消息”)语句将在信息行窗格语句将在信息行窗格(或窗格或窗格0)内显示内显示“消息消息”字样。字样。(2)手动处理状态栏的手动处理状态栏的ON_UPDATE_COMMAND_UI更新消息,并在处理更新消息,并在处理函数中调用函数中调用CCmdUI:SetText函数。函数。(3)调用调用CStatusBar:SetPaneText函数更新任何窗格函数更新任何窗格(包括信息行窗格包括信息行窗格)中的文本。此函数原型描述如下:中的文本。此函数原型描述如下:BOOL SetPaneText(int nIndex,LPCTSTR lpszNewText,BOOL bUpdate=TRUE);6.3状态栏状态栏例例Ex_Status 在状态栏的最右边两个窗格中显示出当前鼠标在窗口客户区在状态栏的最右边两个窗格中显示出当前鼠标在窗口客户区的位置。的位置。(1)将前面的单文档应用程序将前面的单文档应用程序Ex_Sdi打开或重新创建;打开或重新创建;(2)将项目工作区窗口切换到将项目工作区窗口切换到ResourceView页面,双击页面,双击“String Table”项项的的“String Table”图标。在字符串列表的最后一行空项上双击鼠标左键,图标。在字符串列表的最后一行空项上双击鼠标左键,如图:如图:(3)该对话框中,可以指定相应的该对话框中,可以指定相应的ID和字符串值,这里加入两个字符串资源和字符串值,这里加入两个字符串资源ID_LEFT和和ID_RIGHT,其字符的多少决定窗格的大小。如图:其字符的多少决定窗格的大小。如图:图图6.17 字符串属性对话框字符串属性对话框添加的字符串图图6.18 添加的字符串资源添加的字符串资源6.3状态栏状态栏(4)打开打开MainFrm.cpp文件,将原先的文件,将原先的indicators数组修改如下:数组修改如下:static UINT indicators=ID_SEPARATOR,/第一个信息行窗格第一个信息行窗格ID_SEPARATOR,/第二个信息行窗格第二个信息行窗格ID_LEFT,/第三个窗格第三个窗格ID_RIGHT,/第四个窗格第四个窗格;(5)必须手工添加消息处理函数原型。打开必须手工添加消息处理函数原型。打开Ex_SdiView.h文件,在文件,在AFX_MSG内增内增加消息处理语句,加消息处理语句,ClassWizard以后允许访问和编辑该代码。以后允许访问和编辑该代码。protected:/AFX_MSG(CEx_SdiView)afx_msg void OnUpdateXY(CCmdUI*pCmdUI);/AFX_MSGDECLARE_MESSAGE_MAP()(6)打开打开Ex_SdiView.cpp文件,在其消息入口处添加消息映射函数:文件,在其消息入口处添加消息映射函数:BEGIN_MESSAGE_MAP(CEx_SdiView,CView)/AFX_MSG_MAP(CEx_SdiView)ON_UPDATE_COMMAND_UI(ID_LEFT,OnUpdateXY)ON_UPDATE_COMMAND_UI(ID_RIGHT,OnUpdateXY)/AFX_MSG_MAP 6.3状态栏状态栏(7)增加修改状态栏指示器的消息映射函数代码,状态栏的窗格需要更新时,应增加修改状态栏指示器的消息映射函数代码,状态栏的窗格需要更新时,应用程序框架自动调用此函数。用程序框架自动调用此函数。void CEx_SdiView:OnUpdateXY(CCmdUI*pCmdUI)pCmdUI-Enable(TRUE);/使窗格文本能被更新使窗格文本能被更新(8)用用ClassWizard在在CEx_SdiView类中加入类中加入WM_MOUSEMOVE(鼠标移动鼠标移动)消息处理函数,并添加下列代码。该函数先获得状态栏对象的指针,然后消息处理函数,并添加下列代码。该函数先获得状态栏对象的指针,然后调用调用SetPaneText函数更新第三和第四窗格中的文本。函数更新第三和第四窗格中的文本。void CEx_SdiView:OnMouseMove(UINT nFlags,CPoint point)CString str;CMainFrame*pFrame=(CMainFrame*)AfxGetApp()-m_pMainWnd;CStatusBar*pStatus=&pFrame-m_wndStatusBar;if(pStatus)str.Format(X=%d,point.x);/格式化文本格式化文本pStatus-SetPaneText(2,str);str.Format(Y=%d,point.y);pStatus-SetPaneText(3,str);CView:OnMouseMove(nFlags,point);6.3状态栏状态栏(9)将将MainFrm.h文件中的受保护变量文件中的受保护变量m_wndStatusBar变成公共变量。变成公共变量。(10)在在Ex_SdiView.cpp文件的开始处增加下列语句:文件的开始处增加下列语句:#include“MainFrm.h”(11)编译并运行,如图。编译并运行,如图。图图6.19 鼠标的位置显示在状态栏上鼠标的位置显示在状态栏上6.3状态栏状态栏改变状态栏的风格改变状态栏的风格 在在MFC的的CStatusBar类中,有两个成员函数可以改变状态栏风格,它们是:类中,有两个成员函数可以改变状态栏风格,它们是:void SetPaneInfo(int nIndex,UINT nID,UINT nStyle,int cxWidth);void SetPaneStyle(int nIndex,UINT nStyle);参数参数nIndex表示要设置的状态栏窗格的索引,表示要设置的状态栏窗格的索引,nID用来为状态栏窗格指定用来为状态栏窗格指定新的新的ID,cxWidth表示窗格的像素宽度,表示窗格的像素宽度,nStyle表示窗格的风格类型,用表示窗格的风格类型,用来指定窗格的外观,例如来指定窗格的外观,例如SBPS_POPOUT表示窗格是凸起来的,见表。表示窗格是凸起来的,见表。6.4交互对象的动态更新交互对象的动态更新 为能使交互对象动态更新,为能使交互对象动态更新,MFC通过通过ClassWizard直接映射交互对象的更新直接映射交互对象的更新命令消息来实现。自动将用户交互对象的命令消息来实现。自动将用户交互对象的ID号与号与ON_UPDATE_COMMAND_UI宏相连接并产生处理更新消息的相应函数。宏相连接并产生处理更新消息的相应函数。例如代码:例如代码:void CEx_SdiView:OnUpdateXY(CCmdUI*pCmdUI)pCmdUI-Enable(TRUE);/使窗格文本能被更新使窗格文本能被更新OnUpdateXY就是映射更新命令消息的消息函数。此消息处理函数只有一个就是映射更新命令消息的消息函数。此消息处理函数只有一个参数,它是指向参数,它是指向CCmdUI对象的指针。对象的指针。CCmdUI 类仅用于类仅用于ON_UPDATE_COMMAND_UI处理函数,它的成员函数将对菜单项、工具处理函数,它的成员函数将对菜单项、工具按钮等用户交互对象起作用,如表。按钮等用户交互对象起作用,如表。6.4交互对象的动态更新交互对象的动态更新例例Ex_T&Mitem菜单项和工具按钮的更新。菜单项和工具按钮的更新。(1)将上例的单文档应用程序项目将上例的单文档应用程序项目Ex_Sdi调入或重新创建。调入或重新创建。(2)将项目工作区窗口切换到将项目工作区窗口切换到ResourceView页面,选中页面,选中Toolbar资源资源IDR_MAINFRAME,然后按下然后按下Ctrl键不放,在资源键不放,在资源IDR_MAINFRAME上上单击鼠标左击后向下拖一下,这时该工具条资源就被复制,新的资源号为单击鼠标左击后向下拖一下,这时该工具条资源就被复制,新的资源号为IDR_MAINFRAME1,将其改为将其改为IDR_NEWBAR。(3)打开打开MainFrm.h文件,在文件,在CMainFrame类中声明一个类中声明一个CToolBar类变量类变量m_wndNewBar。6.4交互对象的动态更新交互对象的动态更新(4)在在CMainFrame:OnCreate中添加下列代码:中添加下列代码:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if(CFrameWnd:OnCreate(lpCreateStruct)=-1)return-1;if(!m_wndToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)|!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)TRACE0(Failed to create toolbarn);return-1;/fail to createif(!m_wndNewBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)|!m_wndNewBar.LoadToolBar(IDR_NEWBAR)TRACE0(Failed to create newbarn);return-1;/fail to createm_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);m_wndNewBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);DockControlBar(&m_wndNewBar);return 0;6.4交互对象的动态更新交互对象的动态更新(5)打开菜单资源打开菜单资源IDR_MAINFRAME,在在“查看查看”菜单下添加一个菜单项菜单下添加一个菜单项“新新工具栏工具栏(&N)”,ID号设定为号设定为ID_VIEW_NEWBAR。(6)打开打开Toolbar资源资源IDR_MAINFRAME,将上例新增的工具按钮同将上例新增的工具按钮同ID_VIEW_NEWBAR菜单关联起来。菜单关联起来。(7)为为CMainFrame类添加一个类添加一个BOOL型的成员变量型的成员变量m_bNewBar。(8)用用ClassWizard在在CMainFrame类中添加菜单类中添加菜单ID_VIEW_NEWBAR的的COMMAND和和UPDATE_COMMAND_UI两个消息处理函数,并添加下列两个消息处理函数,并添加下列代码:代码:void CMainFrame:OnViewNewbar()m_bNewBar=!m_bNewBar;ShowControlBar(&m_wndNewBar,m_bNewBar,FALSE);void CMainFrame:OnUpdateViewNewbar(CCmdUI*pCmdUI)m_bNewBar=m_wndNewBar.IsWindowVisible();pCmdUI-SetCheck(m_bNewBar);(9)编译运行并测试。打开编译运行并测试。打开“查看查看”菜单,可以看到菜单,可以看到“新工具栏新工具栏”菜单前面有一菜单前面有一个个“”,同时有一个工具按钮被选中,单击该工具按钮或选择,同时有一个工具按钮被选中,单击该工具按钮或选择“新工具新工具栏栏”菜单,则新创建的工具栏不见,同时这个工具按钮恢复原状,而菜单,则新创建的工具栏不见,同时这个工具按钮恢复原状,而“新新工具栏工具栏”菜单前面没有任何标记。若将代码中的菜单前面没有任何标记。若将代码中的SetCheck改为改为SetRadio,则则“”变成了变成了“”,这就是交互对象的更新效果。,这就是交互对象的更新效果。作业作业1.p376:8,112.p428:实验实验11