工具栏是windows应用程序中一个非常重要的图形界面元素,它提供了一组顺序排列的带有位图图标的按钮。工具栏把常见的菜单命令集合起来,以按钮的形式提给给用户使用,目的是为了方便用户操作。
一般情况下,当我们在菜单资源设计完成后,会为一些常用的菜单命令设置相应的按钮,摆放到工具栏,以便用户操作,菜单项的消息ID和工具栏对应按钮的消息ID是设置成一样,使得它们具有相同的消息响应函数,工具栏相当于给用户提供了一个快捷通道,下面我们就演示如何添加工具栏。
绘图子菜单
我们首先在IDR_MAINFRAME菜单项中增加一个绘图的子菜单,该子菜单有三个按钮,分别是Rect,RounRect,Grid按钮,其ID分别是IDM_RECT, IDM_ROUNDRECT,IDM_GRID, 消息响应函数在视类中实现,它们对应的消息响应函数如下:
/****************************************************************
*函数名称:OnRectDraw
*功 能:绘制矩形
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnRectDraw()
/****************************************************************
*函数名称:OnRoundRectDraw
*功 能:绘制圆角矩形
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnRoundRectDraw()
/****************************************************************
*函数名称:OnGridDraw
*功 能: 绘制网格
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnGridDraw()
以上就完成了菜单项的功能添加,代码具体实现下面给出。
创建工具栏
类层次结构
CObject |
└ CCmdTarget |
└ CWnd |
└ CControlBar |
└ CToolBar |
CToolBar类派生于CControlBar类,而后者又是派生于wnd类,因此工具栏也是一个窗口,类CControlBar是所有控件条类(CStatusBar、CToolBar、CDialogBar、CReBar和COleResizeBar)的基类。控件条一般是一个在框架窗口左边或右边的窗口。
创建工具栏的步骤
1.创建工具栏资源
2.构造CToorBar对象
3.调用Create或CreateEx函数创建Windows工具栏,并把它与已经创建的CToolBar对象关联起来
4.调用LoadToolBar函数加载工具栏资源
一、创建工具栏资源
创建步骤:
选择资源项/右键点击ToolBar/新建
工具栏效果:
每个位图的ID分别设置成和绘图子菜单下的菜单项相同,即IDM_RECT, IDM_ROUNDRECT,IDM_GRID,这个他们都具有了相同的消息响应函数。
二、构造ToolBar对象
我们在主框架CMainFrame类中添加m_wndDrawBar成员函数,并在OnCreate函数中调用Create函数和加载位图资源。
三、创建和加载工具栏
由于工具栏一般都是附属在框架窗口上面,因此工具栏的创建需要在框架创建完成之后,同时我们一般都会需要设置工具栏可以停靠在窗口之上面,具体代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//创建主框架
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndDrawBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndDrawBar.LoadToolBar(IDR_TOOLBAR_NUMBER))
{
TRACE0("未能创建数字栏\n");
return -1; // 未能创建
}
//以上部分就完成工具栏的创建,如下三行代码是,指定工具栏可停靠
//允许控制条被停靠
m_wndDrawBar.EnableDocking(CBRS_ALIGN_ANY);
//指定框架窗口可以被停靠
EnableDocking(CBRS_ALIGN_ANY);
//使该控件条停靠于框架窗
DockControlBar(&m_wndDrawBar);
return 0;
}
四、主要函数解读
(一)EnableDocking
第一个EnableDocking函数是CControlBar的成员函数,用于说明该控制条允许处于停靠状态, 其函数声明如下:
void EnableDocking( DWORD dwStyle );
dwStyle
指定是否允许控件条处于停靠状态和它在父窗口中停靠的位置。
停靠位置参数如下:
· CBRS_ALIGN_TOP 允许停靠在客户区的上方。
· CBRS_ALIGN_BOTTOM 允许停靠在客户区的下方。
· CBRS_ALIGN_LEFT 允许停靠在客户区的左边。
· CBRS_ALIGN_RIGHT 允许停靠在客户区的右边。
· CBRS_ALIGN_ANY 允许停靠在客户区的任意一边
· CBRS_FLOAT_MULTI 允许在一个小的框架窗口中浮动有多个控件条。
为0时(即没有指明标志)不允许停靠控件条。
第二个EnableDocking函数是CFrameWnd的成员函数,调用该函数 使得框架窗口可以被停靠, 其函数声明如下:
void DockControlBar(CControlBar* pBar, UINT nDockBarID=0, LPCRECT lpRect = NULL);
参数:
pBar
指向将停靠的控件条。
nDockBarID
决定框架窗口的哪一边用于停靠,可为0或以下之中的一个或多个:
· AFX_IDW_DOCKBAR_TOP 停靠到框架窗口的顶部。
· AFX_IDW_DOCKBAR_BOTTOM 停靠到框架窗口底部。
· AFX_IDW_DOCKBAR_LEFT 停靠到框架窗口左边。
· AFX_IDW_DOCKBAR_RIGHT 停靠到框架窗口右边。
如果为0,控件条可以在目标框架窗口中任意可停靠的地方停靠。
lpRect
以屏幕坐标表示目标框架窗口非用户区中可被控件条停靠的位置。
工具栏功能实现
工具栏对应按钮的消息响应函数和菜单项的消息响应函数是一致的,分别实现绘制矩形,绘制圆角矩形,绘制网格,具体代码如下:
/****************************************************************
*函数名称:OnRectDraw
*功 能:绘制矩形
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnRectDraw()
{
//清理上一次绘图
Invalidate(TRUE);
//使得窗口能重新绘制
UpdateWindow();
CClientDC dc(this);
CBrush Brush(RGB(255,0,0));
CBrush *pOldBrush = dc.SelectObject(&Brush);
//绘制矩形
dc.Rectangle(50, 50, 200,200);
dc.SelectObject(pOldBrush);
}
/****************************************************************
*函数名称:OnRoundRectDraw
*功 能:绘制圆角矩形
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnRoundRectDraw()
{
//清理上一次绘图
Invalidate(TRUE);
//使得窗口能重新绘制
UpdateWindow();
CClientDC dc(this);
CBrush Brush(RGB(0,0,255));
CBrush *pOldBrush = dc.SelectObject(&Brush);
//绘制圆角矩形
dc.RoundRect(CRect(50,50,200,200),CPoint(100,100));
dc.SelectObject(pOldBrush);
}
/****************************************************************
*函数名称:OnGridDraw
*功 能: 绘制网格
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CWndStyleView::OnGridDraw()
{
//清理上一次绘图
Invalidate(TRUE);
//使得窗口能重新绘制
UpdateWindow();
CClientDC dc(this);
CPen pen(PS_SOLID,1, RGB(0, 255,0));
CPen *pOldpen = dc.SelectObject(&pen);
//绘制网格
for (int i = 50; i < 200; i += 10)
{
dc.MoveTo(50,i);
dc.LineTo(200 ,i);
dc.MoveTo(i,50);
dc.LineTo(i,200);
}
dc.SelectObject(pOldpen);
}
运行效果:
工具栏显示开关
接下来我们需要完成该绘图工具栏的显示开关,即设置复选标记菜单,当点击该菜单项时,绘图工具栏消失,再次点击时绘图工具栏出现。我们这里把开关位于“视图”子菜单下,代码实现在框架类中完成。工具栏的显示需要使用到框架类中的ShowControlBar函数,其函数声明如下:
void ShowControlBar(CControlBar* pBar,BOOL bShow,BOOL bDelay);
参数:
pBar 指向将显示或隐含的控件条。
bShow 如果为TRUE,则指定控件条将被显示;如果为FALSE,则隐藏。
bDelay 如果为TRUE,则延迟显示控件条;如果为FALSE,则立即显示。
说明:调用此成员函数显示或隐藏一个控件条。
在工具栏显示开关中,我们需要完成消息响应函数和菜单项状态更新,即ON_COMMAND和ON_UPDATE_COMMAND_UI两个消息,其具体代码如下:
void CMainFrame::OnUpdateGraphBar(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
if (pCmdUI != NULL)
{
//设置菜单项的状态
pCmdUI->SetCheck(m_wndDrawBar.IsWindowVisible());
}
}
/****************************************************************
*函数名称:OnShowGraphBar
*功 能:显示图形工具栏
*作 者:Jin
*日 期:2016年11月26日
****************************************************************/
void CMainFrame::OnShowGraphBar()
{
// TODO: 在此添加命令处理程序代码
ShowControlBar(&m_wndDrawBar,!m_wndDrawBar.IsWindowVisible(),FALSE);
}
运行效果: