1.3 工具栏应用实例
工具栏是应用程序界面的重要组成元素之一,它包含了一组命令按钮,用于执行某些菜单项的功能。通常情况下,将应用程序中常用的功能放置在工具栏中,这样可以方便用户操作,省去了在级联菜单中层层查找菜单项的困扰。在MFC类库中,CToolBar类封装了工具栏的基本功能,在本节中,将详细介绍利用CToolBar类设计各种工具栏。
工具栏在开发应用程序时经常用到,本节将介绍几种特色工具栏的实现方法。
实例007 带图标的工具栏
这是一个可以启发思维的实例
实例位置:光盘\mingrisoft\01\007
实例说明
默认情况下,MFC中提供的工具栏只能显示简单的图像。本实例实现了一个带有图标的工具栏按钮,效果如图1.8所示。
图1.8 带图标的工具栏
技术要点
工具栏CToolBar提供了一个GetToolBarCtrl方法,用于获得一个CToolBarCtrl对象,该对象提供了一个SetImageList方法,用于设置与工具栏关联的图像列表控件。只要在程序中创建一个图像列表,并向图像列表中添加图标,将其与工具栏关联,那么工具栏按钮就会显示出图像。
实现过程
(1)新建一个文档/视图结构的应用程序。
(2)在框架类中定义一个CImageList对象m_Imagelist。
(3)在框架类的OnCreate方法中创建图像列表,并向图像列表中添加图标。创建工具栏,将工具栏与图像列表关联,设置工具栏按钮的大小,代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; //创建图像列表,向图像列表中添加图标 m_Imagelist.Create(32,32,ILC_COLOR24|ILC_MASK,0,1); for (int i=0;i<9;i++) { m_Imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON1+i)); //加载图标资源 } //创建工具栏 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("Failed to create toolbar\n"); return-1; //fail to create } m_wndToolBar.GetToolBarCtrl().SetImageList(&m_Imagelist); //管理图像列表 m_wndToolBar.GetToolBarCtrl().SetButtonSize(CSize(40,40)); //设置按钮大小 m_wndToolBar.GetToolBarCtrl().SetBitmapSize(CSize(30,30)); //设置图像大小 if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return-1; //fail to create } m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; }
举一反三
根据本实例,读者可以:
实现具有热点效果的工具栏。
实例008 带下拉菜单的工具栏
本实例可以美化界面、简化操作
实例位置:光盘\mingrisoft\01\08
实例说明
本实例是对工具栏功能的扩充,可以将工具栏上按钮的并列项以菜单的形式显示,方便用户操作。运行程序,单击工具栏按钮旁边的下三角按钮,将弹出一个下拉菜单,如图1.9所示。
图1.9带下拉菜单的工具栏
技术要点
下三角按钮是通过CToolBar类的SetButtonStyle方法和CToolBarCtrl类的SetExtendedStyle方法实现的。
SetButtonStyle方法用来设置工具栏按钮的风格,语法如下:
void SetButtonStyle( int nIndex, UINT nStyle );
参数说明:
● nIndex:按钮的索引。
● nStyle:按钮的风格。可以有以下取值。
■ TBBS_BUTTON:标准按钮。
■ TBBS_SEPARATOR:分隔线。
■ TBBS_CHECKBOX:复选风格。
■ TBBS_GROUP:按钮组。
■ TBBS_CHECKGROUP:复选按钮组。
SetExtendedStyle方法用于设置工具栏控件的扩展风格,语法如下:
DWORD SetExtendedStyle( DWORD dwExStyle ) const;
参数说明:
● dwExStyle:系统定义的工具栏控件风格,取值TBSTYLE_EX_DRAWDDARROWS,可以实现下三角按钮功能。
实现过程
(1)新建一个MFC的单文档结构应用程序,命名为ToolbarWithMenu。
(2)在工程中添加Menu资源,设置ID属性为IDR_MENU1,为菜单添加两个子菜单项。
(3)主要程序代码如下:
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("Failed to create toolbar\n"); return -1; } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; } m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); //设置工具栏具有下拉按钮 //获得添加下拉按钮的工具栏打开按钮风格 DWORD dwStyle= m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_OPEN)); dwStyle|=TBSTYLE_DROPDOWN; //添加下拉按钮风格 m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_OPEN), dwStyle); //设置下拉按钮风格 return 0; } void CMainFrame::OnToolbarDropdown(NMTOOLBAR*pnmh,LRESULT*plr) //按下下拉按钮 { CWnd*pWnd; switch(pnmh->iItem) { case ID_FILE_OPEN: //如果是工具栏打开按钮 pWnd=&m_wndToolBar; //获得工具栏窗口指针 break; default: return; } CMenu menu; menu.LoadMenu(IDR_MENU1); //加载菜单资源 CMenu*pPopup=menu.GetSubMenu(0); //获得子菜单 ASSERT(pPopup); CRect rc; pWnd->SendMessage(TB_GETRECT,pnmh->iItem,(LPARAM)&rc); //获得区域 pWnd->ClientToScreen(&rc); //转换为屏幕坐标系区域 pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.left ,rc.bottom,this,&rc); //显示弹出菜单 } void CMainFrame::OnSubmenu() //菜单项单击时间 { AfxMessageBox("你按下的是子菜单"); //弹出消息提示框 } void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point) { CMenu menu; menu.LoadMenu(IDR_LMENU); //加载菜单资源 CMenu*pPopup=menu.GetSubMenu(0); //获得子菜单 pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x,point.y, this,NULL); //显示弹出菜单 }
举一反三
根据本实例,读者可以:
开发右击客户区弹出菜单程序;
实现右击工具栏弹出菜单。
实例009 可调整按钮位置的工具栏
本实例可以美化界面、简化操作
实例位置:光盘\mingrisoft\01\09
实例说明
本实例实现了工具栏上两个按钮互换位置的功能。运行程序,选择菜单“查看”/“改变按钮位置”,程序会将“新建”按钮和“保存”按钮进行位置调换。调换前、后的效果分别如图1.10和图1.11所示。
图1.10 调换前
图1.11 调换后
技术要点
本实例通过CToolBar类的SetButtonInfo方法实现,SetButtonInfo方法用来设置工具栏按钮的相关信息,语法如下:
void SetButtonInfo( int nIndex, UINT nID, UINT nStyle, int iImage );
参数说明:
● nIndex:工具栏上按钮的位置。
● nID:工具栏按钮在工程中的资源ID值。
● nStyle:工具栏按钮的风格。
● iImage:工具栏按钮的图片索引值。
实现过程
(1)新建名为ToolbarAjustBtn的单文档MFC工程。
(2)修改Menu资源IDR_MAINFRAME,在菜单“查看”下新建子菜单,设置ID属性为ID_VIEW,设置Caption属性为“改变按钮位置”。
(3)主要程序代码。
菜单ID_VIEW的实现函数,实现调用MoveButton函数完成工具栏按钮的调整,代码如下:
void CMainFrame::OnView() { this->MoveButton(0,2); //调用MoveButton函数调整工具栏按钮位置 }
函数MoveButton实现工具栏上不同位置的按钮相互调换,代码如下:
void CMainFrame::MoveButton(int oldpos,int newpos) { UINT newID,oldID; newID=m_wndToolBar.GetItemID(newpos); //获得工具栏按钮ID oldID=m_wndToolBar.GetItemID(oldpos); //获得工具栏按钮ID m_wndToolBar.SetButtonInfo(oldpos,newID,0,newpos); //设置工具栏按钮信息 m_wndToolBar.SetButtonInfo(newpos,oldID,0,oldpos); //设置工具栏按钮信息 }
举一反三
根据本实例,读者可以:
控制工具栏按钮的显示。
实例010 动态设置是否显示工具带栏按钮文本
本实例可以美化界面、简化操作
实例位置:光盘\mingrisoft\01\010
实例说明
工具栏中的按钮并不一定是都显示按钮文本的,用户可以根据当前的操作随时变化,这样可以提高程序的应用性。本实例根据用户的操作来调整工具栏按钮文本的显示。程序首先创建一个新的工具栏,然后根据数据库中的数据来决定哪个工具栏按钮可以显示。工具栏转换前如图1.12所示,转换后如图1.13所示。
图1.12 不显示工具栏按钮文本
图1.13 显示工具栏按钮文本
技术要点
本实例中涉及创建工具栏、设置工具栏高度等技术。在程序中可以使用CToolBar来定义一个工具栏对象,通过GetToolBarCtrl方法来获取CToolBarCtrl类对象。通过CToolBarCtrl类对象可以关联图像列表。要设置工具栏按钮高度可以通过SetHeight方法来实现,语法如下:
void SetHeight( int cyHeight );
参数说明:
● cyHeight:要设置的工具栏高度。
实现过程
(1)新建一个基于对话框的应用程序。
(2)在工程中导入8个图标资源,并向对话框中添加一个按钮控件。
(3)在对话框的头文件中声明变量,代码如下:
CToolBar m_ToolBar; //工具栏对象 CimageList m_ImageList; //列表视图对象 BOOL m_bText; //是否显示按钮文本
(4)在对话框初始化时创建工具栏,代码如下:
BOOL CToolTipDlg::OnInitDialog() { CDialog::OnInitDialog(); // …系统代码省略 //创建图像列表 m_ImageList.Create(16,16,ILC_COLOR24|ILC_MASK,1,1); //向图像列表中添加图标 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7)); m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8)); UINT array[11]; for(int i=0;i<11;i++) { if(i==3 || i==7 || i==9) array[i] = ID_SEPARATOR; //第4、8、10个按钮为分隔条 else array[i] = i+1001; } CString str[]={"新建","打开","保存","","剪切","复制","粘贴","","打印","","帮助"}; //创建工具栏 m_ToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP); m_ToolBar.SetButtons(array,11); //设置工具栏按钮 for(i=0;i<11;i++) { m_ToolBar.SetButtonText(i,str[i]); //设置工具栏按钮文本 } m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList); //关联图像列表 m_ToolBar.SetSizes(CSize(24,24),CSize(16,16)); //设置按钮和图标的大小 RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); m_bText = FALSE; return TRUE; }
(5)添加UpdateToolBar函数,该函数用于设置是否显示工具栏按钮文本,代码如下:
void CToolTipDlg::UpdateToolBar(BOOL bUpdate) { if(bUpdate) { m_ToolBar.SetSizes(CSize(32,32),CSize(16,16)); //设置按钮和图标的大小 m_ToolBar.SetHeight(36); //设置工具栏高度 RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); } else { m_ToolBar.SetSizes(CSize(24,24),CSize(16,16)); //设置按钮和图标的大小 m_ToolBar.SetHeight(28); //设置工具栏高度 RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); } }
(6)处理“转换”按钮的单击事件,控制工具栏按钮是否显示,代码如下:
void CToolTipDlg::OnButtonupdate() { m_bText = !m_bText; UpdateToolBar(m_bText); }
举一反三
根据本实例,读者可以:
根据需要设置工具栏按钮是否可用。
实例011 具有提示功能的工具栏
这是一个可以提高分析能力的实例
实例位置:光盘\mingrisoft\01\011
实例说明
在文档/视图结构的应用程序中,默认情况下,当鼠标在工具栏按钮上停留时,会出现一个工具提示条。运行本实例,将鼠标停留在工具栏的某一个按钮上,即可看到该工具按钮的提示信息,效果如图1.14所示。
图1.14 具有提示功能的工具栏
技术要点
使工具栏具有提示功能,需要同时具备两个条件。一是工具栏具有CBRS_TOOLTIPS风格,二是工具栏的父窗口需要处理TTN_NEEDTEXT通知消息。在MFC类库中,CFrameWnd默认处理了TTN_NEEDTEXT通知消息,因此,在文档/视图结构的应用程序中,只要工具栏具有CBRS_TOOLTIPS风格,就能够显示提示信息。
如果在对话框中添加TTN_NEEDTEXT通知消息,需要在消息映射部分添加如下代码:
ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify)
其中,OnToolTipNotify是处理TTN_NEEDTEXT消息的函数,函数原型如下:
OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult);
参数说明:
● id:是发送消息的控件ID,但此处没有用,因为控件ID可以来自于pNMHDR。
● pNMHDR:是一个NMHDR结构指针(实际应该是NMTTDISPINFO结构指针),NMHDR结构记录了发送消息的控件ID、句柄等信息。
● pResult:表示结果代码指针,TTN_NEEDTEXT消息可以忽略该参数。
实现过程
(1)新建一个基于对话框的应用程序。
(2)在对话框类中定义一个CToolBar变量m_wndToolBar。在工作区的资源视图中创建一个工具栏资源,如图1.15所示。
图1.15 工具栏资源设计
(3)在对话框的OnInitDialog方法中创建工具栏,代码如下:
//创建工具栏 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |CBRS_SIZE_DYNAMIC|CBRS_BORDER_TOP ) || !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1)) { TRACE0("Failed to create toolbar\n"); return-1; //fail to create } //设置图像和按钮的大小,以适合演示按钮文本 m_wndToolBar.GetToolBarCtrl().SetBitmapSize(CSize(16,16)); //设置显示图像大小 m_wndToolBar.GetToolBarCtrl().SetButtonSize(CSize(32,32)); //设置工具栏按钮大小 //设置按钮文本 m_wndToolBar.SetButtonText(0,"新建"); m_wndToolBar.SetButtonText(1,"打开"); m_wndToolBar.SetButtonText(2,"保存"); m_wndToolBar.SetButtonText(4,"剪切"); m_wndToolBar.SetButtonText(5,"复制"); m_wndToolBar.SetButtonText(6,"粘贴"); m_wndToolBar.SetButtonText(8,"打印"); m_wndToolBar.SetButtonText(10,"帮助");
(4)在对话框的消息映射部分添加TTN_NEEDTEXT消息映射宏。
ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify)
(5)向对话框中添加OnToolTipNotify方法,代码如下:
BOOL CToolHintDlg::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; UINT nID=pNMHDR->idFrom; //获取工具栏按钮ID int index=m_wndToolBar.GetToolBarCtrl().CommandToIndex(nID); //根据ID获取按钮索引 m_wndToolBar.GetButtonText(index,m_ToolText); //获取按钮文本 pTTT->lpszText=m_ToolText.GetBuffer(0); //设置显示的提示信息 pTTT->hinst = AfxGetResourceHandle(); return(TRUE); }
举一反三
根据本实例,读者可以:
实现具有提示功能的各种控件。