440 likes | 649 Views
第 5 章 菜单、工具栏和状态栏. 5.1.1 文档应用程序的 MFC 类结构. 用 MFC AppWizard(exe) 创建一个默认的单文档应用程序 Ex_SDI ,将项目工作区窗口切换到“ ClassView( 类视图 )” 页面,可以看到构成 Ex_SDI 应用程序框架的 MFC 类结构,如图所示。再创建一个默认的多文档应用程序 Ex_MDI ,可以看到如图所示的 MFC 类结构。. 5.1.2 项目的文件组织. Visual C++ 6.0 中,项目中所有的源文件都采用文件夹的方
E N D
5.1.1 文档应用程序的MFC类结构 用MFC AppWizard(exe)创建一个默认的单文档应用程序Ex_SDI,将项目工作区窗口切换到“ClassView(类视图)”页面,可以看到构成Ex_SDI 应用程序框架的MFC类结构,如图所示。再创建一个默认的多文档应用程序Ex_MDI,可以看到如图所示的MFC类结构。
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)
5.1.2 项目的文件组织 还有相应的Debug(调试)、Res(资源)等子文件夹。 程序项目Win32 Release版本,它与Release的区别在于:Debug版本的运行程序有相应的调试信息码,而Release版本的运行程序没有,但Release版本的运行程序经过代码的优化,其程序的运行效率被最大提升。 通过选择“编译”“放置可远行配置”菜单命令,在图所示的对话框中,选择“Ex_SDI-Win32 Release”,然后单击[确定]按钮,编译后即可。
5.2 菜单 Windows程序都有各自的菜单。为了使Windows程序更容易 操作,许多程序员对于菜单的设计都遵循下列一些规则: • 若选择某菜单项会弹出一对话框,那么在该菜单项文本后 • 有“…”。 • (2) 若某项菜单有子菜单,那么在该菜单项文本后有“”。 • (3) 若菜单项需要助记符,则用括号将带下划线的字母括起来。助记符与Alt构成一个组合键,当按住“Alt”键不放,再敲击(4) • 该字母时,对应的菜单项就会被选中。 (4)若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。所谓“快捷键”是一个组合键,如Ctrl+N,使用时是先按下“Ctrl”健不放,然后再按“N”键。任何时候按下快捷键,相应的菜单命令都会被执行
5.1.1 更改应用程序菜单 • 通过菜单编辑器直接修改菜单资源IDR_MAINFRAME可以实现添加和修改应用程序菜单,如下示例过程。 • [例Ex_MenuSDI] 更改应用程序菜单 • (1) 创建一个默认的单文档应用程序Ex_MenuSDI。 • (2) 在项目工作区窗口中选择ResourceView页面,双击 资“Menu”项中的IDR_MAINFRAME,则菜单编辑器窗口 出现在主界面的右边,项目Ex_MenuSDI相应的菜单资 源在菜单编辑器窗口中显示出来。 (3) 按快捷键Ctrl+R,弹出“插入资源”对话框,在资源类型中选定“Menu”,如图
5.1.1 更改应用程序菜单 单击[新建]按钮,系统就会为应用程序添加一个新的菜单资源,并自动赋给它一个默认的标识符名称(第一次为DR_MENU1,以后依次为IDR_MENU2、IDR_MENU3、...),同时自动打开这个新的菜单资源。
5.1.1 更改应用程序菜单 在Menu资源的ID_MENU1上右击鼠标,从弹出的快捷菜单中选择“Properties”命令,在这里可以重新指定菜单资源ID,设置菜单资源的语言和条件,这个条件用来决定菜单资源包含到哪个环境中,例如当指定条件为_DEBUG,则菜单资源只存在于Debug编译环境中。
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类。
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 ); }
5.2.2 使用键盘快捷键 加速键也往往被称为键盘快捷键,加速键也是一种资源,它的显示、编辑过程和菜单相似。 例如下面的示例过程是为前面两个菜单ID_VIEW_TEST和ID_TEST_RETURN定义键盘快捷键:先打开上例的项目工作区窗口中Accelerator的资源项,双击IDR_MAINFRAME,出现如图的加速键资源列表。
5.2.2 使用键盘快捷键 (2) 建立一新的加速键,双击加速键列表的最下端的空行,弹出如图所示的“Accel Properities”对话框,可设置的属性如表所示 。
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 • 将执行相应的菜单命令。
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号。
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使菜单更新。
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。
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。
5.2.3 菜单的编程控制 • 选择“查看”菜单“Resource Symbols…”命令, “资源符号”对话框,它能对应用程序中的资源标识符进行管理。 • 程序中添加的菜单项需要一个标识值,最好用一个标识符来代替这个值,因此这里通过“资源符号”对话框来创建一个新的标识符。
5.2.3 菜单的编程控制 (3) 单击[新建]按钮,在名字(Name)框中输入一个新的标识符ID_NEW_MENUITEM。在值(Value)框中,输入该ID的值,系统要求用户定义的ID值应大于15(0X000F)而小于61440(0XF000)。保留默认的ID值101,单击[确定]按钮。 “New Symbol”对话框:
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; }
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) 编译运行并测试。 这样当选择菜单“编辑”“新的菜单项”命令后,就会弹一个对话框,显示“你选中了新的菜单项”消息。
5.2.4 使用快捷菜单 • 1. 快捷菜单实现函数 • 用资源编辑器和MFC库的CMenu::TrackPopupMenu函数可以很容易地创建这样的菜单,CMenu::TrackPopupMenu 函数原型如下: BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL ); 该函数用来显示一个浮动的弹出式菜单,其位置由各参数决定。nFlags表示菜单在屏幕显示的位置以及鼠标按钮标志,nFlags的值及其对其他参数的影响
5.2.4 使用快捷菜单 • 2. 示例 • 本示例是在前面Ex_SDI基础上进行的,当显示主 • 菜单IDR_MAINFRAME时,右击鼠标弹出“查看”菜 • 单的子菜单,当显示菜单IDR_MENU1时,右击鼠 • 标弹出“测试”菜单的子菜单。。 [续例Ex_MenuSDI] 使用快捷菜单 (1) 打开前面的单文档应用程序Ex_MenuSDI。 (2) 用MFC ClassWizard在CMainFrame类添加 WM_CONTEXTMENU消息映射。 (3) 编译运行并测试。
5.3.1 使用工具栏编辑器 选择菜单“文件”“打开工作区”,将前面的单文档应用程序Ex_MenuSDI调入。在项目工作区窗口中选择ResourceView页面,双击“Toolbar”项中的IDR_MAINFRAME则工具栏编辑器出现在主界面的右边。
5.3.1 使用工具栏编辑器 1. 创建一个新的工具栏按钮 在新建的工具栏中,最右端总有一个空按钮,双击该按钮弹出其属性对话框,在ID框中输入其标识符名称,其右端又出现一个新的空按钮。 • 2. 移动一个按钮 • 在工具栏中移动一个按钮,用鼠标左键点中它并拖动至相 应位置即可。如果用户拖动它离开工具栏位置,则此按钮从工具栏中消失。 • 3. 删除一个按钮 • 将选取中的按钮拖离工具栏,则该按钮就消失了。但若选中按钮后,单击Delete键并不能删除一个按钮,只是将按钮中的图形全部以背景色填充。
5.3.1 使用工具栏编辑器 • 4. 在工具栏中插入空格 • 在工具栏中插入空格有以下几种情况: • 如果按扭前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。 • 如果按钮前有空格而按钮后没有空格,拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。 • 如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。 • 5. 工具栏按钮属性的设置 • 双击某按钮弹出其属性对话框,如图所示。
5.3.1 使用工具栏编辑器 工具栏按钮属性对话框 属性对话框中的各项说明见表
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显示测试菜单”。
5.3.2 工具按钮和菜单项相结合 设计的两个工具栏按钮 (5) 编译运行并测试。程序运行后,将鼠标移至刚才设计的第一个工具按钮处,这时在状态栏上显示出“返回应用程序主菜单”信息,若稍等片刻会弹出提示小窗口,显示出“返回主菜单”字样,单击新添加的这两个按钮,会执行相应的菜单命令。
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。
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;
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; }
5.3.3 多个工具栏的使用 AFX_IDW_TOOLBAR是系统内部的工具栏子窗口标识,并将AFX_IDW_TOOLBAR+1的值表示默认的状态栏子窗口标识。 当打开“查看”菜单时,单击“工具栏”菜单时,显示或隐藏的工具栏不是原来的工具栏而是新添加的工具栏。我们需要重新指定工具栏子窗口的标识,并使其值等于AFX_IDW_TOOLBAR + 10。 (6) 编译运行,结果如图所示
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时表示立即显示或隐藏。
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 ); // 显示主工具栏 }
5.3.3 多个工具栏的使用 • 编译运行并测试,结果如图所示,左边是一开始 • 运行的结果,右边是单击工具按钮运行的结果。
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这三个键的状态。
5.4.2 状态栏的常用操作 MFC的CStatusBar类封装了状态栏的大部分操作。 • 1. 增加和减少窗格 • 状态栏中的窗格分为信息行窗格和指示器窗格两类。在状 • 态 栏中增加一个信息行窗格,则只需在indicators数组中的 • 适当位置中增加一个ID_SEPARATOR标识即可;若在状态 • 栏中增加一个用户指示器窗格,则在indicators数组中的适 • 当位置增加一个在字符串表中定义过的资源ID,其字符串 • 的长度表示用户指示器窗格的大小。若状态栏减少一个 • 窗格,操作与增加相类似,需减少indicators数组元素即可。 • 2. 在状态栏上显示文本 • 调用CStatusBar::SetPaneText函数可以更新任何窗格(包 • 括信息行窗格)中的文本。此函数原型描述如下:
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, };
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); }
5.4.2 状态栏的常用操作 (5) 将MainFrm.h文件中的受保护变量m_wndStatusBar变成 公共变量。 (6) 在Ex_SDIMouseView.cpp文件的开始处增加下列语句: #include "Ex_SDIMouseView.h" #include "MainFrm.h" (7) 编译并运行,结果如图所示。
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; // 获得主窗口中的状态栏指针
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); } 状态栏窗格的风格类型
习 题 (1) MFC单文档和多文档应用程序一般是由哪些类构成? (2) 什么是助记符?它是如何在菜单中定义的? (3) 若对同一个菜单用ClassWizard分别在视图类和主框架窗口 类CMainFrame都处理其COMMAND消息,并在它们的函数中添加相同的代码,则当用户选择该菜单后,会有什么样的结果?为什么? (4) 什么是键盘快捷键?它是如何定义的? (5) 什么是快捷菜单?用程序实现一般需要哪些步骤? (6) 状态栏的作用是什么?状态栏的窗格分为几类?如何添加和减少相应的窗格? (7) 若状态栏只有一个用户定义的指示器窗格(其ID号为ID_TEXT_PANE),应如何定义?若当用户在客户区双击鼠标,在该窗格中显示“双击鼠标”字样,则应如何编程? (8) 上机练习本章的示例。