00. 目录
01. 案例概述
Visual C++在设计对话框资源的时候,有一个控件选择的工具栏,该工具栏上的按钮只有一个是有效的。案例效果如下图所示。
02. 开发环境
系统环境:Windows 10
开发环境:Visual Studio 2019
03. 关键技术
使用工具栏类CToolBar的SetButtonInfo方法可以修改工具栏按钮的样式,方法中的nStyle参数就是用来设置按钮具体的样式,将样式设置为TBBS_GROUP和TBBS_CHECKGROUP就可以实现单选效果。TBBS_GROUP决定哪些按钮是一组单选按钮,用TBBS_CHECKGROUP分别设置每个按钮。
04. 程序设计
(1)新建一个基于单文档视图结构的应用程序。
(2)在CMainFrame类中声明一个CToolBar对象和CImageList对象。
protected: // 控件条嵌入成员
//CToolBar m_wndToolBar;
CStatusBar m_wndStatusBar;
CToolBar m_ToolBar;
CImageList m_ImageList;
CRect m_RectFloat;
(3)在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("未能创建工具栏\n");
// return -1; // 未能创建
//}
if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -1; // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
TODO: 如果不需要可停靠工具栏,则删除这三行
//m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
//EnableDocking(CBRS_ALIGN_ANY);
//DockControlBar(&m_wndToolBar);
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP |
CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
//创建图像列表
m_ImageList.Create(24, 24, ILC_COLOR32 | ILC_MASK, 0, 0);
//向图像列表中添加图像
CString strPath;
HICON hIcon;
for (int i = 0; i < 10; i++)
{
strPath.Format(TEXT(".\\res\\toolbar\\%02d.ico"), i);
hIcon = (HICON)LoadImage(NULL, strPath, IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
m_ImageList.Add(hIcon);
}
//设置工具栏按钮
m_ToolBar.SetButtons(NULL, 6);
//设置工具栏首按钮的状态
UINT nStyle;
m_ToolBar.SetButtonInfo(0, ID_POINTER, TBBS_GROUP | TBBS_CHECKGROUP, 0);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(0);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(0, nStyle);
m_ToolBar.SetButtonInfo(1, ID_PEN, TBBS_CHECKGROUP, 1);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(1);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(1, nStyle);
m_ToolBar.SetButtonInfo(2, ID_RECTANGLE, TBBS_CHECKGROUP, 2);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(2);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(2, nStyle);
m_ToolBar.SetButtonInfo(3, ID_PARALLE, TBBS_CHECKGROUP, 3);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(3);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(3, nStyle);
m_ToolBar.SetButtonInfo(4, ID_ROUND, TBBS_CHECKGROUP, 4);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(4);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(4, nStyle);
m_ToolBar.SetButtonInfo(5, ID_ROUNDRECT, TBBS_CHECKGROUP, 5);
//获取工具栏按钮的状态
nStyle = m_ToolBar.GetButtonStyle(5);
//设置工具栏按钮是否另行显示
nStyle &= ~TBBS_WRAPPED;
//设置工具栏按钮的样式
m_ToolBar.SetButtonStyle(5, nStyle);
//刷新工具栏
m_ToolBar.Invalidate();
//重新计算框架内窗体布局
m_ToolBar.GetParentFrame()->RecalcLayout();
//设置工具栏按钮大小
m_ToolBar.GetToolBarCtrl().SetButtonSize(CSize(31, 32));
//设置工具栏图标列表
m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList);
//设置工具栏停靠方式
m_ToolBar.EnableDocking(0);
//设置窗口停靠方式
EnableDocking(0);
m_ToolBar.SetWindowTextW(TEXT("工具栏"));
GetWindowRect(&m_RectFloat);
//计算工具栏显示位置
CPoint point(m_RectFloat.left + 100, m_RectFloat.top + 100);
//将工具栏进行浮动显示
FloatControlBar(&m_ToolBar, point, CBRS_ALIGN_LEFT);
return 0;
}
(4)将命令ID映射到处理函数
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_COMMAND_RANGE(ID_POINTER, ID_POINTER + 6, OnMenuClick)
// ON_WM_MENUSELECT()
END_MESSAGE_MAP()
void CMainFrame::OnMenuClick(UINT nId)
{
}
05. 秘笈心法
工具栏按钮的Group属性
取值TBBS_GROUP用法和单选按钮控件(Radio Button)的Group属性相同,单选按钮控件的Group属性只在一组按钮中的第一按钮上设置,其后的单选按钮都和第一个设置Group属性的按钮是一组,一个窗体只要有一个Group属性的单选按钮控件就可以实现单选效果。