原文:http://blog.youkuaiyun.com/touzani/archive/2007/05/18/1614244.aspx
工具条/栏(tool bar)和状态条/栏(status bar)是构建友好GUI程序的通用标准,但它们并不是Windows API 的标准部件,而是由应用程序框架(MFC)增加 的一类控件。
CObject → CCmdTarget → CWnd → CControlBar → CToolBar / CStatusBar
BUTTON ID_FILE_NEW
BUTTON ID_FILE_OPEN
BUTTON ID_FILE_SAVE
BUTTON ID_EDIT_CUT
BUTTON ID_EDIT_COPY
BUTTON ID_EDIT_PASTE
BUTTON ID_FILE_PRINT
BUTTON ID_APP_ABOUT
l 在VC项目工作区的资源视图页中展开 “Student/Student.rc”中的“Toolbar”资源列表,双击IDR_MAINFRAME打开工具栏编辑器(见下图)
l 选择当前按钮:单击位于VS窗口中部的 工具条编辑窗口上部工具条栏中的所需按钮;
l 修改位图:对当前按钮,可以利用“图 像”菜单、图像编辑器工具条和(位于属性窗口上部的)颜色窗口,在中部的图像编辑器窗口中绘制和修改当前按钮的位图;
l 修改属性:在属性窗口中可以
n 选择该按钮所对应的(菜单项)ID
n 修改该按钮位图的宽和高
n 键入/修改该按钮所对应的提示文本 (/n后的为按钮的浮动提示文本)
l 删除按钮:将按钮拖离工具条即可
l 添加按钮:
n 将工具条最右边的空白按钮拖到你想加入 按钮的位置
n 用“图像”菜单、图像编辑器工具条和颜 色窗口来绘制按钮的位图(在空白按钮上绘图后,VS会自动在其右边添加一个新的空白按钮)
n 在属性窗口中选择该按钮所对应的(菜单 项)ID
n 还可以修改该按钮位图的宽和高、键入/ 修改该按钮所对应的提示文本
l 分组:左/右拖动按钮半个按钮宽度,可 将其
n 与右边/左边的按钮分开成不同的组
n 与左边/右边的按钮合并成同一个组
① 在使用应用程序向导创建程序时,在“MFC 应用程序向导”对话框的“用户界面功能”页的“工具栏”选项中,没有选“标准停靠”单选钮,则需要自己加入工具条;
② 或者原有的工具条不够用,需要加入第2个工具 条;
③ 或者在程序运行当中需要在多个工具条中切换;
l 在项目工作区的“资源视图”页中的 Toolbar资源表项上单击鼠标右键,在弹出的浮动菜单中选“插入Toolbar”菜单项,VS会自动创建一个ID为IDR_TOOLBAR1的空工具 条
l 可在该工具条中加入若干图形按钮(如 Z、L、W)
l 在属性窗口中修改工具条的ID(如 IDR_MYTB),选择按钮对应的ID(如ID_NAME_ZS、ID_NAME_LS、ID_NAME_WW)
l 创建新工具条资源
l 打开头文件MainFrm.h,在 CMainFrame类中加入工具条类CToolBar的对象m_ToolBar作为公共数据成员:(缺省的工具条对象为CToolBar m_wndToolBar; )
l 在CMainFrame类中 WM_CREATE消息响应函数OnCreate(若无该函数则创建它)中的return 0;语句之前加入下列代码:
CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |
if (!m_ToolBar.Create(this)) {// 创建工具条
return -1; // 创建失败
if (!m_ToolBar.LoadToolBar(IDR_MYTB)) { // 装入工具条
return -1; // 装入失败
m_ToolBar.SetBarStyle(m_ToolBar.GetBarStyle() | CBRS_GRIPPER | CBRS_TOOLTIPS |
② 在框架窗口中加入多个工具条:
l 创建新工具条资源
l 打开头文件MainFrm.h,在 CMainFrame类中加入工具条类CToolBar的对象m_ToolBar作为公共数据成员:
l 在原有的OnCreate函数内加入似 ①的创建与装入工具条的代码,但要注意代码的顺序,且不需重复语句EnableDocking(CBRS_ALIGN_ANY); 参见下面代码的红色部分(其余部分为自动生成的缺省代码):
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) ||
return -1; // 未能创建
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
return -1; // 未能创建
if (!m_wndStatusBar.Create(this) ||
return -1; // 未能创建
// TODO: 如果不需要工具栏可停靠,则删除这三行
return 0;
③ 显示/隐藏/切换工具条:
l 似②创建若干工具条资源
l 在OnCreate函数内加入相应代 码,来创建与装入工具条
l 在这些代码后面,加上隐藏暂不显示的工 具条的代码,如
ShowControlBar(&m_ToolBar, FALSE, FALSE);
void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay );
l 在菜单资源中添加显示/隐 藏/ 切换工具条的菜单项(如“视图/切换工具栏”ID_CHANGE_TOOL_BAR),在某一窗口派生类(如视图类 CStudentView)中创建该菜单项的消息响应函数(如OnChangeToolBar),在该函数中隐藏/显示/切换工具条,例如:
CMainFrame *pFrmWnd = (CMainFrame*)GetTopLevelFrame();
pFrmWnd->ShowControlBar(&pFrmWnd->m_wndToolBar, FALSE, FALSE);
pFrmWnd->ShowControlBar(&pFrmWnd->m_ToolBar, TRUE, FALSE);
pFrmWnd->ShowControlBar(&pFrmWnd->m_ToolBar, FALSE, FALSE);
pFrmWnd->ShowControlBar(&pFrmWnd->m_wndToolBar, TRUE, FALSE);
void SetButtonInfo( int nIndex, UINT nID, UINT nStyle, int iImage );
l 可在CStudenView类中设置一 个整数型数据成员m_iAddNum (int m_iAddNum;)
l 在类的构造函数中将该变量初始化为0 (m_iAddNum = 0;)
l 在消息响应函数OnAdd中,将该变量 加一 (m_iAddNum++;)
l 在消息响应函数OnDel中,将该变量 减一 (m_iAddNum--;)
l 在“删除”菜单项的UI更新响应函数 OnUpdateDel中,根据m_iAddNum的值设置“删除”按钮(和菜单项)的禁止与激活状态:
l 在“添加”菜单项的UI更新响应函数 OnUpdateAdd中,根据m_iAddNum的值设置“添加”按钮(和菜单项)的禁止与激活状态:
l 可在CStudenView类中设置一 个布尔型数据成员zs (bool zs;)
l 在类的构造函数中将该变量初始化为假 (zs = false;)
l 在消息响应函数OnNameZs中,切 换该变量的真假 (zs = !zs;)
l 在Z按钮(ID_NAME_ZS)UI 更新响应函数OnUpdateNameZs中,根据zs的值来设置按钮是否按下:
缺省状态条在CMainFrame类中对应于保护型数据成员 CStatusBar m_wndStatusBar; 在MainFrm.cpp 文件的前面部分中有数组:
m_wndStatusBar.SetPaneText(0, L"Message line for first pane");
BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE );
l 将CMainFrame类中的保护数据 成员m_wndStatusBar改为公共的
l 在头文件MainFrm.h中加入窗格 ID的枚举变量。如
enum SBID {prompt, xName, xVal, yName, yVal};
l 去掉原indicators数组中的三 个状态指示窗格的ID,加入若干(n个)消息行窗格ID (ID_SEPARATOR),其中第1个(nIndex = 0)用于显示提示信息,其余的(n个)用作应用程序的数据显示。如
ID_SEPARATOR, // 提示 nIndex = 0
ID_SEPARATOR, // "x:" nIndex = 1
ID_SEPARATOR, // "y:" nIndex = 3
l 在创建状态条的代码后(如在 CMainFrame::OnCreate函数的尾部),用状态条的成员函数SetPaneInfo来设置每个窗格的ID、风格和宽度(单位似对话框,为 1/4英文字母),其函数原型为
void SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxWidth );
n SBPS_NOBORDERS 窗格周围无三维边框
n SBPS_POPOUT 窗格突出显示
n SBPS_DISABLED 不画文本
n SBPS_STRETCH 伸缩窗格以填满空间(每个状态条中只能有一个窗格可以被设置成伸缩的)
n SBPS_NORMAL 不伸缩、无边框、不凸显
l 在应用程序中用函数 SetPaneText动态修改窗格中的文本串。如
CMainFrame *pFrmWnd = (CMainFrame*)GetTopLevelFrame();
_itow_s(point.x, buf, 20, 10);
pFrmWnd->m_wndStatusBar.SetPaneText(pFrmWnd->xVal, buf);
_itow_s(point.y, buf, 20, 10);
pFrmWnd->m_wndStatusBar.SetPaneText(pFrmWnd->yVal, buf);
CView::OnMouseMove(nFlags, point);