1 / 44

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

第 5 章 菜单、工具栏和状态栏. 5.1.1 文档应用程序的 MFC 类结构. 用 MFC AppWizard(exe) 创建一个默认的单文档应用程序 Ex_SDI ,将项目工作区窗口切换到“ ClassView( 类视图 )” 页面,可以看到构成 Ex_SDI 应用程序框架的 MFC 类结构,如图所示。再创建一个默认的多文档应用程序 Ex_MDI ,可以看到如图所示的 MFC 类结构。. 5.1.2 项目的文件组织. Visual C++ 6.0 中,项目中所有的源文件都采用文件夹的方

kitra
Download Presentation

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

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. 第5章 菜单、工具栏和状态栏

  2. 5.1.1 文档应用程序的MFC类结构 用MFC AppWizard(exe)创建一个默认的单文档应用程序Ex_SDI,将项目工作区窗口切换到“ClassView(类视图)”页面,可以看到构成Ex_SDI 应用程序框架的MFC类结构,如图所示。再创建一个默认的多文档应用程序Ex_MDI,可以看到如图所示的MFC类结构。

  3. 5.1.2 项目的文件组织 Visual C++ 6.0中,项目中所有的源文件都采用文件夹的方 式进行管理的,每一个类的源代码均保存同名的h和cpp文件。 .opt 关于开发环境的参数文件,如工具格位置等信息 .aps(AppStudio File) 资源辅助文件,二进制格式 .clw ClassWizard 信息文件 .dsp(DeveloperStudio Project) 项目文件 .plg 编译信息文件 .mdp(Microsoft DevStudio Project) 旧版本的项目文件 .bsc 用于浏览项目信息 .map 执行文件的映像信息纪录文件 .pch(Pre-Compiled File) 预编译文件,可以加快编译速度,但是文件非常大 .pdb(Program Database) 记录程序有关的一些数据和调试信息 .ncb 无编译浏览文件(no compile browser)

  4. 5.1.2 项目的文件组织 还有相应的Debug(调试)、Res(资源)等子文件夹。 程序项目Win32 Release版本,它与Release的区别在于:Debug版本的运行程序有相应的调试信息码,而Release版本的运行程序没有,但Release版本的运行程序经过代码的优化,其程序的运行效率被最大提升。 通过选择“编译”“放置可远行配置”菜单命令,在图所示的对话框中,选择“Ex_SDI-Win32 Release”,然后单击[确定]按钮,编译后即可。

  5. 5.2 菜单 Windows程序都有各自的菜单。为了使Windows程序更容易 操作,许多程序员对于菜单的设计都遵循下列一些规则: • 若选择某菜单项会弹出一对话框,那么在该菜单项文本后 • 有“…”。 • (2) 若某项菜单有子菜单,那么在该菜单项文本后有“”。 • (3) 若菜单项需要助记符,则用括号将带下划线的字母括起来。助记符与Alt构成一个组合键,当按住“Alt”键不放,再敲击(4) • 该字母时,对应的菜单项就会被选中。 (4)若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。所谓“快捷键”是一个组合键,如Ctrl+N,使用时是先按下“Ctrl”健不放,然后再按“N”键。任何时候按下快捷键,相应的菜单命令都会被执行

  6. 5.1.1 更改应用程序菜单 • 通过菜单编辑器直接修改菜单资源IDR_MAINFRAME可以实现添加和修改应用程序菜单,如下示例过程。 • [例Ex_MenuSDI] 更改应用程序菜单 • (1) 创建一个默认的单文档应用程序Ex_MenuSDI。 • (2) 在项目工作区窗口中选择ResourceView页面,双击 资“Menu”项中的IDR_MAINFRAME,则菜单编辑器窗口 出现在主界面的右边,项目Ex_MenuSDI相应的菜单资 源在菜单编辑器窗口中显示出来。 (3) 按快捷键Ctrl+R,弹出“插入资源”对话框,在资源类型中选定“Menu”,如图

  7. 5.1.1 更改应用程序菜单 单击[新建]按钮,系统就会为应用程序添加一个新的菜单资源,并自动赋给它一个默认的标识符名称(第一次为DR_MENU1,以后依次为IDR_MENU2、IDR_MENU3、...),同时自动打开这个新的菜单资源。

  8. 5.1.1 更改应用程序菜单 在Menu资源的ID_MENU1上右击鼠标,从弹出的快捷菜单中选择“Properties”命令,在这里可以重新指定菜单资源ID,设置菜单资源的语言和条件,这个条件用来决定菜单资源包含到哪个环境中,例如当指定条件为_DEBUG,则菜单资源只存在于Debug编译环境中。

  9. 5.1.1 更改应用程序菜单 在菜单的空位置上双击鼠标左键,则出现它的属性对话框。通过其属性对话框为菜单ID_MENU1添加一个顶层弹出菜单项“测试(&T)”,并在该菜单下添加一个子菜单项“返回(&R)”,ID设为ID_TEST_RETURN,需要再次强调的是,符号&用来指定后面的字符是一个助记符。 (7) 打开Ex_MenuSDI程序菜单资源IDR_MAINFRAME,在“查看”菜单的最后添加一个子菜单项“显示测试菜单(&M)”,ID设为ID_VIEW_TEST。 (8) 为CMainFrame类添加一个CMenu类型的成员变量m_NewMenu,CMenu类是用来处理菜单的一个MFC类。

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

  11. 5.2.2 使用键盘快捷键 加速键也往往被称为键盘快捷键,加速键也是一种资源,它的显示、编辑过程和菜单相似。 例如下面的示例过程是为前面两个菜单ID_VIEW_TEST和ID_TEST_RETURN定义键盘快捷键:先打开上例的项目工作区窗口中Accelerator的资源项,双击IDR_MAINFRAME,出现如图的加速键资源列表。

  12. 5.2.2 使用键盘快捷键 (2) 建立一新的加速键,双击加速键列表的最下端的空行,弹出如图所示的“Accel Properities”对话框,可设置的属性如表所示 。

  13. 5.2.2 使用键盘快捷键 • (3) 在上述对话框中,选择Ex_MenuSDI添加的“显示测试 • 菜单”菜单项ID_VIEW_TEST作为要联用的加速键的ID号,单 • 击[下一键]按钮,并按下Ctrl+1作为此加速键的键值。 • (4) 按同样的方法,为菜单项ID_TEST_RETURN添加加 • 速键Ctrl+2。需要说明的是,为了使其他用户能查看并 • 使用该加速键,还需在相应的菜单项文本后面添加加 • 速键内容。例如,可将ID_VIEW_TEST菜单项的标题 • 改成“显示测试菜(&M)\tCtrl+1”,其“\t”是将后面的“Ctrl+1” • 定位到一个表位。 • (5) 编译运行并测试。当程序运行后,按“Ctrl+1”和“Ctrl+2 • 将执行相应的菜单命令。

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

  15. 5.2.3 菜单的编程控制 • 3. 添加菜单项 • 当菜单创建后,用户可以调用AppendMenu或InsertMenu 函数来添加一些菜单项。AppendMenu是将菜单项添加在菜单的末尾处,而InsertMenu在菜单的指定位置处插入菜单项,并将后面的菜单项依次下移。 BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0,LPCTSTR l pszNewItem = 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 ); • 4.删除菜单项 • 调用DeleteMenu函数可将指定的菜单项删除,需要注意的是:调用该函数后,不管菜单依附的窗口是否改变,都应调用CWnd::DrawMenuBar使菜单更新。

  16. 5.2.3 菜单的编程控制 函数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。

  17. 5.2.3 菜单的编程控制 int GetMenuString( UINT nIDItem, CString& rString, UINT nFlags ) const; 该函数用来获得由nIDItem指定菜单项位置(以0为基数)的菜单项的文本内容(字符串),并由rString参数返回,当nFlags为MF_BYPOSITION时,nPosition表示菜单项的位置(第一个菜单项位置为0)。 CMenu* GetSubMenu( int nPos ) const; 该函数用来获得指定菜单的弹出式菜单的菜单句柄。该弹出式菜单位置由参数nPos指定,开始的位置为0。若菜单不存在,则创建一个临时的菜单指针。 下面的示例过程是利用CMenu成员函数向应用程序菜单中添加并处理一个菜单项: [例Ex_Menu] 菜单项的编程控制 (1) 创建一个默认的单文档应用程序Ex_Menu。

  18. 5.2.3 菜单的编程控制 • 选择“查看”菜单“Resource Symbols…”命令, “资源符号”对话框,它能对应用程序中的资源标识符进行管理。 • 程序中添加的菜单项需要一个标识值,最好用一个标识符来代替这个值,因此这里通过“资源符号”对话框来创建一个新的标识符。

  19. 5.2.3 菜单的编程控制 (3) 单击[新建]按钮,在名字(Name)框中输入一个新的标识符ID_NEW_MENUITEM。在值(Value)框中,输入该ID的值,系统要求用户定义的ID值应大于15(0X000F)而小于61440(0XF000)。保留默认的ID值101,单击[确定]按钮。 “New Symbol”对话框:

  20. 5.2.3 菜单的编程控制 (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; // 关闭系统自动更新菜单状态 SysMenu>EnableMenuItem(ID_NEW_MENUITEM,MF_BYCOMMAND|MF_ENABL // 激活菜单项 DrawMenuBar(); // 更新菜单 return 0; }

  21. 5.2.3 菜单的编程控制 (5) 用MFC 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) 编译运行并测试。 这样当选择菜单“编辑”“新的菜单项”命令后,就会弹一个对话框,显示“你选中了新的菜单项”消息。

  22. 5.2.4 使用快捷菜单 • 1. 快捷菜单实现函数 • 用资源编辑器和MFC库的CMenu::TrackPopupMenu函数可以很容易地创建这样的菜单,CMenu::TrackPopupMenu 函数原型如下: BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL ); 该函数用来显示一个浮动的弹出式菜单,其位置由各参数决定。nFlags表示菜单在屏幕显示的位置以及鼠标按钮标志,nFlags的值及其对其他参数的影响

  23. 5.2.4 使用快捷菜单 • 2. 示例 • 本示例是在前面Ex_SDI基础上进行的,当显示主 • 菜单IDR_MAINFRAME时,右击鼠标弹出“查看”菜 • 单的子菜单,当显示菜单IDR_MENU1时,右击鼠 • 标弹出“测试”菜单的子菜单。。 [续例Ex_MenuSDI] 使用快捷菜单 (1) 打开前面的单文档应用程序Ex_MenuSDI。 (2) 用MFC ClassWizard在CMainFrame类添加 WM_CONTEXTMENU消息映射。 (3) 编译运行并测试。

  24. 5.3.1 使用工具栏编辑器 选择菜单“文件”“打开工作区”,将前面的单文档应用程序Ex_MenuSDI调入。在项目工作区窗口中选择ResourceView页面,双击“Toolbar”项中的IDR_MAINFRAME则工具栏编辑器出现在主界面的右边。

  25. 5.3.1 使用工具栏编辑器 1. 创建一个新的工具栏按钮 在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在ID框中输入其标识符名称,其右端又出现一个新的空按钮。 • 2. 移动一个按钮 • 在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相 应位置即可。如果用户拖动它离开工具栏位置,则此按钮从工具栏中消失。 • 3. 删除一个按钮 • 将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中按钮后,单击Delete键并不能删除一个按钮,只是将按钮中的图形全部以背景色填充。

  26. 5.3.1 使用工具栏编辑器 • 4. 在工具栏中插入空格 • 在工具栏中插入空格有以下几种情况: • 如果按扭前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。 • 如果按钮前有空格而按钮后没有空格,拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。 • 如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。 • 5. 工具栏按钮属性的设置 • 双击某按钮弹出其属性对话框,如图所示。

  27. 5.3.1 使用工具栏编辑器 工具栏按钮属性对话框 属性对话框中的各项说明见表

  28. 5.3.2 工具按钮和菜单项相结合 工具按钮和菜单项相结合是指当选择工具按钮或菜单命令时,操作结果是一样的。 Ex_MenuSDI基础上进行的,通过两个工具按钮分别显示主菜单IDR_MAINFRAME和菜单IDR_MENU1。 (1) 打开前面的单文档应用程序Ex_MenuSDI。 (2) 利用工具栏编辑器设计两个工具按钮,位置内容如图所示。 (3) 双击刚才设计的第一个工具按钮,弹出该工具按钮的属性对话框,将该工具按钮的ID号设为ID_TEST_RETURN,在提示框内键入“返回应用程序主菜单\n返回主菜单”。 (4) 双击刚才设计的第二个工具按钮,弹出该工具按钮的属性对话框,将该工具按钮的ID号设为ID_VEW_TEST,在提示框内键入“显示测试菜单\n显示测试菜单”。

  29. 5.3.2 工具按钮和菜单项相结合 设计的两个工具栏按钮 (5) 编译运行并测试。程序运行后,将鼠标移至刚才设计的第一个工具按钮处,这时在状态栏上显示出“返回应用程序主菜单”信息,若稍等片刻会弹出提示小窗口,显示出“返回主菜单”字样,单击新添加的这两个按钮,会执行相应的菜单命令。

  30. 5.3.3 多个工具栏的使用 在用MFC AppWizard创建的文档应用程序中往往只有一个工具栏,但在实际应用中,常常需要多个工具栏。 (1) 将项目工作区切换到ResourceView页面,展开Toolbar(工具栏)资源,用鼠标单击IDR_MAINFRAME不松开,按下Ctrl键,移动鼠标将IDR_MAINFRAME拖到Toolbar资源名称上,复制了工具栏默认资源IDR_MAINFRAME,复制后的资源标识系统自动设为IDR_MAINFRAME1。 (2) 右击工具栏资源IDR_MAINFRAME1,从弹出的快捷菜单中选择Properties命令,如图所示,将ID设为IDR_TOOLBAR1。

  31. 5.3.3 多个工具栏的使用 (3) 双击IDR_TOOLBAR1,打开工具栏资源,按图删除不要 的工具按钮。 (4) 在CMainFrame类中添加一个成员变量m_wndTestBar,变 量类型为CToolBar。CToolBar类封装了工具栏的操作。 (5) 在CMainFrame::OnCreate函数中添加工具栏创建代码: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

  32. 5.3.3 多个工具栏的使用 在CMainFrame::OnCreate函数中添加下面的工具栏创建代码 int nRes = m_wndTestBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_ FLYBY | CBRS_SIZE_DYNAMIC, CRect(0,0,0,0), AFX_IDW_TOOLBAR + 10); if (!nRes || !m_wndTestBar.LoadToolBar(IDR_TOOLBAR1)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } … m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); m_wndTestBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); DockControlBar(&m_wndTestBar); return 0; }

  33. 5.3.3 多个工具栏的使用 AFX_IDW_TOOLBAR是系统内部的工具栏子窗口标识,并将AFX_IDW_TOOLBAR+1的值表示默认的状态栏子窗口标识。 当打开“查看”菜单时,单击“工具栏”菜单时,显示或隐藏的工具栏不是原来的工具栏而是新添加的工具栏。我们需要重新指定工具栏子窗口的标识,并使其值等于AFX_IDW_TOOLBAR + 10。 (6) 编译运行,结果如图所示

  34. 5.3.3 多个工具栏的使用 (7) 本例希望IDR_TOOLBAR1工具栏和IDR_MENU1菜单栏在一起, 不是一开始就出现。还需要调用CFrameWnd类的成员函数ShowControlBar来使程序一开始运行时隐藏工具栏IDR_TOOLBAR1。在CMainFrame::OnCreate函数中添加下列代码: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { … ShowControlBar( &m_wndTestBar, FALSE, FALSE ); // 关闭测试工具栏 return 0; } 代码中,ShowControlBa函数有三个参数,第一个用来指定要操作的工具栏或状态栏指针,第二个是一个布尔型,为TRUE时表示显示,否则表示隐藏,第三个用来表示是否延迟显示或隐藏,为FALSE时表示立即显示或隐藏。

  35. 5.3.3 多个工具栏的使用 (8) 在CMainFrame::OnViewTest和CMainFrame::OnTestReturn 函数中添加下列代码: void CMainFrame::OnViewTest() { … ShowControlBar( &m_wndTestBar, TRUE, FALSE ); // 显示测试工具栏 ShowControlBar( &m_wndToolBar, FALSE, FALSE ); // 关闭主工具栏 } void CMainFrame::OnTestReturn() { … ShowControlBar( &m_wndTestBar, FALSE, FALSE ); // 关闭测试工具栏 ShowControlBar( &m_wndToolBar, TRUE, FALSE ); // 显示主工具栏 }

  36. 5.3.3 多个工具栏的使用 • 编译运行并测试,结果如图所示,左边是一开始 • 运行的结果,右边是单击工具按钮运行的结果。

  37. Static UINT indicators[]= { ID_SEPARATOR, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, } 5.4.1 状态栏的定义 数组中的元素是一些标识常量或是字符串资源的ID号。 默认的indicator数组包含了四个元素:ID_SEPARATOR ID_INDICATOR_CAPS ID_INDICATOR_NUM ID_INDICATOR_SCRL 分别显示出CapsLock、NumLock和ScrollLock这三个键的状态。

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

  39. 5.4.2 状态栏的常用操作 BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE ); lpszNewText表示要显示的字符串。nIndex是表示设置的窗格索引(第一个窗格的索引为0)。若bUpdate为TRUE,则系统自动更新显示的结果。 下面来看一个示例。 [例Ex_SDIMouse] 将鼠标在窗口客户区的位置显示在状态栏上 (1) 创建一个默认的单文档应用程序Ex_SDIMouse。 (2) 将项目工作区切换到ClassView页面,展开CMainFrame 所有项,双击构造函数CMainFrame,在文档窗口中出现该 函数的定义,在它的前面就是状态栏数组的定义。 (3) 将状态栏indicators数组的定义改为下列代码: static UINT indicators[] = { ID_SEPARATOR, ID_SEPARATOR, };

  40. 5.4.2 状态栏的常用操作 (4) 由于鼠标移动消息WM_MOUSEMOVE在CMainFrame类映射后不起作用,只能映射到CEx_SDIMouseView类中。CMainFrame类定义的成员变量,需要在CEx_SDIMouseView类中添加访问CMainFrame类的代码。Ex_SDIMouseView::OnMouseMove函数代码如下: void CEx_SDIMouseView::OnMouseMove(UINT nFlags, CPoint point) { CString str; CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd; // 获得主窗口指针 CStatusBar* pStatus=&pFrame->m_wndStatusBar; // 获得主窗口中的状态栏指针 if (pStatus) { str.Format("X=%d, Y=%d",point.x, point.y); // 格式化文本 pStatus->SetPaneText(1,str); // 更新第二个窗格的文本 } CView::OnMouseMove(nFlags, point); }

  41. 5.4.2 状态栏的常用操作 (5) 将MainFrm.h文件中的受保护变量m_wndStatusBar变成 公共变量。 (6) 在Ex_SDIMouseView.cpp文件的开始处增加下列语句: #include "Ex_SDIMouseView.h" #include "MainFrm.h" (7) 编译并运行,结果如图所示。

  42. 5.4.3 改变状态栏的风格 在MFC的CStatusBar类中,有两个成员函数可以改变状态栏风格,它们是: void SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxWidth ); void SetPaneStyle( int nIndex, UINT nStyle ); 其中,参数nIndex表示要设置的状态栏窗格的索引,nID用来为状态栏窗格指定新的ID,cxWidth表示窗格的像素宽度,nStyle表示窗格的风格类型,用来指定窗格的外观。 例如,将OnMouseMove函数修改为下列代码,则结果如图所示。void CEx_SDIMouseView::OnMouseMove(UINT nFlags, CPoint point) { CString str; CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd; // 获得主窗口指针 CStatusBar* pStatus=&pFrame->m_wndStatusBar; // 获得主窗口中的状态栏指针

  43. 5.4.3 改变状态栏的风格 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); } 状态栏窗格的风格类型

  44. 习 题 (1) MFC单文档和多文档应用程序一般是由哪些类构成? (2) 什么是助记符?它是如何在菜单中定义的? (3) 若对同一个菜单用ClassWizard分别在视图类和主框架窗口 类CMainFrame都处理其COMMAND消息,并在它们的函数中添加相同的代码,则当用户选择该菜单后,会有什么样的结果?为什么? (4) 什么是键盘快捷键?它是如何定义的? (5) 什么是快捷菜单?用程序实现一般需要哪些步骤? (6) 状态栏的作用是什么?状态栏的窗格分为几类?如何添加和减少相应的窗格? (7) 若状态栏只有一个用户定义的指示器窗格(其ID号为ID_TEXT_PANE),应如何定义?若当用户在客户区双击鼠标,在该窗格中显示“双击鼠标”字样,则应如何编程? (8) 上机练习本章的示例。

More Related