工具栏是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("未能创建数字栏 "); 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); }运行效果: