1 / 32

第 6 章菜单、工具栏和状态栏

第 6 章菜单、工具栏和状态栏. 6.1 菜单 6.2 工具栏 6.3 状态栏 6.4 交互对象的动态更新. 图 6.1 File 菜单. 6.1 菜单. 对于菜单的显示都遵循下列一些规则: 若点击某菜单项会弹出一对话框,那么在该菜单项文本后有 “ …” 。 若某项菜单有子菜单,那么在该菜单项文本后有 “  ” 。 菜单项需要助记符,用括号将带下划线的字母括起来。助记符与 Alt 构成一个组合键,当按住 “ Alt ” 键不放,再敲击该字母时,对应的菜单项就会被选中。

amil
Download Presentation

第 6 章菜单、工具栏和状态栏

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第6章菜单、工具栏和状态栏 • 6.1 菜单 • 6.2 工具栏 • 6.3 状态栏 • 6.4 交互对象的动态更新

  2. 图6.1 File菜单 6.1菜单 • 对于菜单的显示都遵循下列一些规则: • 若点击某菜单项会弹出一对话框,那么在该菜单项文本后有“…”。 • 若某项菜单有子菜单,那么在该菜单项文本后有“”。 • 菜单项需要助记符,用括号将带下划线的字母括起来。助记符与Alt构成一个组合键,当按住“Alt”键不放,再敲击该字母时,对应的菜单项就会被选中。 • 若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。任何时候按下快捷键,相应的菜单命令都会被执行。

  3. 菜单的空位置 图6.2 菜单编辑器 6.1菜单 • 6.1.1用编辑器设计菜单 • 编辑菜单 • 在菜单的空位置上双击鼠标左键,则出现它的属性对话框,如图。

  4. 图6.3 菜单属性对话框 6.1菜单

  5. 菜单项被拖动的位置 图6.4 拖动菜单项 图6.5 添加的菜单项 6.1菜单 • 需要注意的是: • 当菜单项的属性中选中了Pop_up时,对话框中ID、Separator和Prompt项无效。 • 增加新的菜单项后,用户可以用鼠标将菜单项拖到其他位置,而当菜单项位置改变时,其属性并没改变。

  6. 图6.6 消息的选择 6.1菜单 • 菜单命令的消息映射 • [例Ex_Mmenu]“成绩输入”菜单项的映射。 • (1)选择“View”菜单“ClassWizard”命令项或按Ctrl+w快捷键,则出现MFC ClassWizard对话框,切换到Message Maps页面。 • (2)从“Class name”列表中选择CMainFrame,在IDs列表中选择ID_SCORE_IN,然后在Messages框中选择COMMAND消息,如图。

  7. 图6.7 添加成员函数对话框 图6.8 菜单命令执行的结果 6.1菜单 • (3)单击[Add Function]按钮或双击COMMAND消息,输入成员函数的名称。如图。 • (4)单击[OK]。选择新增加的成员函数,单击[Edit Code]按钮(或直接在函数名双击鼠标左键),就可以在此成员函数中添加一些代码。例如: • void CMainFrame::OnScoreIn() • { // TODO: Add your command handler code here • AfxMessageBox("现在就输入成绩吗?"); • } • (5)编译并运行。在应用程序的顶层菜单上,单击“成绩输入”菜单项或按Alt+S组合键,如图。

  8. 最下端的空行 图6.9 示例Ex_Sdi的加速键资源 6.1菜单 • 6.1.2使用键盘快捷键 • (1)先打开上例的项目工作区窗口中Accelerator的资源项,双击IDR_MAINFRAME,如图。

  9. 图6.10 “Accel Properities”对话框 6.1菜单 • (2)要建立一新的加速键,双击加速键列表的最下端的空行,如图,其中可设置的属性如表 • (3)在上述对话框中,选择在Ex_Sdi示例中添加的“成绩输入”菜单项的ID号ID_SCORE_IN作为要联用的加速键的ID号,单击[Next Key Typed],按下Ctrl+1作为此加速键的键值。

  10. 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 );

  11. 6.1菜单 • 需要注意的是: • nFlags为MF_BYPOSITION时,nPosition表示新菜单项要插入的具体位置,为0时表示第一个菜单项,为 -1时,将菜单项添加菜单的末尾处。 • nFlags的标志中,可以用“|”(按位或)来组合,例如MF_CHECKED|MF_STRING等。有些组合是不允许的,例如MF_DISABLED、MF_ENABLED和MF_GRAYED,MF_STRING、MF_OWNERDRAW、MF_SEPARATOR和位图,MF_CHECKED和MF_UNCHECKED 都不能组合在一起。 • 当菜单项增加后,不管菜单依附的窗口是否改变,都应调用CWnd::DrawMenuBar来更新菜单。

  12. 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。若菜单不存在,则创建一个临时的菜单指针。

  13. 图6.11 “Resource Symbols”对话框 图6.12 “New Symbol”对话框 6.1菜单 • 给系统菜单添加一个菜单项 • [例Ex_SysMenu] 向应用系统菜单中添加一个菜单项。 • (1)打开一个单文档应用程序项目,若没有可按前面提及的方法进行创建。 • (2)选择“View”菜单“Resource Symbols…”命令,如图。 • (3)单击[New],如图。在Name框中,可以指定一个用于菜单项的ID号。在Value框中,可以定义该ID的值,系统要求定义的ID值应大于15(0X000F)而小于61440(0XF000)。选择默认的ID值101,单击[OK]按钮。

  14. 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)编译运行并测试。

  15. 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时,若击在菜单外面,菜单立刻消失。

  16. 6.1菜单 • [例Ex_Menu]创建弹出菜单。 • (1)选择“Insert”菜单“Resource”命令或按Ctrl+R快捷键,向应用程序项目添加一个新的菜单资源(默认的ID号为 IDR_MENU1)。 • (2)用菜单编辑器,为该菜单资源中的顶层菜单的第一项加一任意标题(实际上该标题无用),在此菜单项下依次添加如下表所示的菜单项。 • (3)将此菜单资源ID号改为IDR_MYFLOATMENU。 • (4)按Ctrl+W快捷键打开ClassWizard,将出现一对话框,询问是“选择一个已存在的类”,还是“创建一个新类”。选择“选择一个已存在的类”项并选定CMainFrame类。

  17. 图6.13 快捷菜单 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)运行并测试。在应用程序的窗口客户区中单击鼠标右键,弹出如图菜单。 “成绩打印”菜单命令没有消息处理函数,因此它是灰显的,用户不能使用它们。若用户选中“成绩输入”菜单命令,则会执行相应的代码。

  18. 空按钮 图6.14 工具栏编辑器窗口 6.2工具栏 • 6.2.1使用工具栏编辑器 • 选择“File”“Open Workspace”,将单文档应用程序Ex_Sdi调入或重新创建。在项目工作区窗口中选择ResourceView标签,双击“Toolbar”项中的IDR_MAINFRAME,则工具栏编辑器出现在主界面的右边,如图。

  19. 6.2工具栏 • (1)创建一个新的工具栏按钮 • 在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在ID框中输入其标识符名称,则在其右端又出现一个新的空按钮。单击该按钮,在编辑器的视窗内进行编辑,这个编辑就是绘制一个按钮位图。 • (2)移动一个按钮 • 在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相应位置即可。如果用户拖动它离开工具栏位置,则此按钮从工具栏中消失。若在移动一个按钮的同时,按下Ctrl键,则在新位置复制一个按钮,新位置可以是同一个工具栏中的其他位置,也可以在不同的工具栏中。 • (3)删除一个按钮 • 前面已提到过,将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中按钮后,单击Delete键并不能删除一个按钮,只是将按钮中的图形全部以背景色填充。 • (4)在工具栏中插入空格 • 如果按钮前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。 • 如果按钮前有空格而按钮后没有空格,拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。 • 如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。

  20. 图6.15 工具栏按钮属性对话框 6.2工具栏 • (5)工具栏按钮属性的设置 • 双击某按钮弹出其属性对话框,如图。

  21. 图6.16 工具栏按钮的设计 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工具栏上,将鼠标指针移至刚才设计的工具按钮处,这时在状态栏上显示出“向系统输入学生成绩”信息,若稍等片刻后,还会弹出提示小窗口,显示出“成绩输入”字样。

  22. Static UINT indicators[]= { ID_SEPARATOR, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, } 图6.17 indicators数组的定义 6.3状态栏 • 6.3.1状态栏的定义 • 用AppWizard创建的SDI或MDI应用程序框架中,有一个静态的indicator数组,它是在MainFrm.cpp文件中定义的,被MFC用作状态栏的定义。

  23. 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 );

  24. 添加的字符串 图6.17 字符串属性对话框 图6.18 添加的字符串资源 6.3状态栏 • [例Ex_Status] 在状态栏的最右边两个窗格中显示出当前鼠标在窗口客户区的位置。 • (1)将前面的单文档应用程序Ex_Sdi打开或重新创建; • (2)将项目工作区窗口切换到ResourceView页面,双击“String Table”项的“String Table”图标。在字符串列表的最后一行空项上双击鼠标左键,如图: • (3)该对话框中,可以指定相应的ID和字符串值,这里加入两个字符串资源ID_LEFT和ID_RIGHT,其字符的多少决定窗格的大小。如图:

  25. 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_MSG • DECLARE_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

  26. 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); • }

  27. 图6.19 鼠标的位置显示在状态栏上 6.3状态栏 • (9)将MainFrm.h文件中的受保护变量m_wndStatusBar变成公共变量。 • (10)在Ex_SdiView.cpp文件的开始处增加下列语句: • #include “MainFrm.h” • (11)编译并运行,如图。

  28. 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表示窗格是凸起来的,见表。

  29. 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处理函数,它的成员函数将对菜单项、工具按钮等用户交互对象起作用,如表。

  30. 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。

  31. 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 toolbar\n"); • return -1; // fail to create } • if (!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 newbar\n"); • return -1; // fail to create } • …… • m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); • m_wndNewBar.EnableDocking(CBRS_ALIGN_ANY); • EnableDocking(CBRS_ALIGN_ANY); • DockControlBar(&m_wndToolBar); • DockControlBar(&m_wndNewBar); • …… • return 0; • }

  32. 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,则“√”变成了“•”,这就是交互对象的更新效果。

More Related