工具栏(ToolBar)是一种非常方便的控件,能大大增加用户操作的效率,但是基于对话框的程序,却不能像使用编辑框(Edit Box)和列表框(List Box)一样,方便地增加工具栏控件。本文将介绍一种在对话框中加入工具栏的方法。
一、 技术要点分析
所有的Windows控件(包括工具栏、编辑框等)都派生自CWnd类,这就意味着,我们可以用窗口类的Create()函数把它们“创建”并显示到另一个窗口(例如对话框)上。把工具栏加入到对话框中正是使用了这样的一种方法。
通常,我们使用CToolBarCtrl类(派生自CWnd类)来创建并管理工具栏控件。使用这个类创建一条工具栏的一般步骤如下:
1.派生一个CToolBarCtrl的对象;
2.调用CToolBarCtrl::Create函数创建工具栏对象;
3.调用CToolBarCtrl::AddBitmap()和CToolBarCtrl::AddString()为工具栏对象加入位图和提示信息;
4.派生一个TBUTTON数组对象进行工具栏中各按钮的具体设置;
5.修改主窗口的OnNotify()函数,以显示工具栏上的提示信息。
以上步骤在下面的范例代码中会有具体体现。
二、 范例程序的建立与主要代码分析
利用Visual C++ 的向导生成一个基于对话框的程序,命名为ToolBarInDial。修改主对话框样式如图1。绘出一条工具栏的位图并建立一选单,设置几个子选单项,然后建立一组工具栏的提示信息串(String Table),一旦鼠标在工具栏某项上停留,就会显示提示信息。下面给出程序中的主要代码。
在主对话框CToolBarInDialDlg的类定义中有如下的变量说明:
CToolBarCtrl ToolBar;
int ButtonCount;
int ButtonBitmap;
BOOL DoFlag;
TBBUTTON m_Button[5];
//设置工具栏上具体信息的变量数组
//主对话框的初始化函数
BOOL CToolBarInDialDlg::OnInitDialog()
{
RECT rect;
//设置工具栏的显示范围
rect.top=0; rect.left=0; rect.right=48; rect.bottom=16;
ToolBar.Create(WS_CHILD|WS_VISIBLE|CCS_TOP|TBSTYLE_TOOLTIPS|CCS_ADJUSTABLE,rect,this,0);
//建立工具栏并设置工具栏的样式
ButtonBitmap=ToolBar.AddBitmap(5,IDB_PLAY); //加入工具栏的位图
ButtonString=ToolBar.AddString(IDS_FIRST);//加入工具栏的提示信息
//以下代码开始设置各具体的按钮
m_Buttons[ButtonCount].iBitmap=
ButtonBitmap+ButtonCount; //ButtonCount初值为0
m_Buttons[ButtonCount].idCommand=ID_PLAY; //工具栏与选单上某子项对应
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
//设置工具栏按钮为可选
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
//设置工具栏按钮为普通按钮
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_LAST;
++ButtonCount;
//类似地设置第二个按钮
m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount;
m_Buttons[ButtonCount].idCommand=ID_STOP;
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_NEXT;
++ButtonCount;
……//省略设置剩下的按钮的代码
ToolBar.AddButtons(ButtonCount,m_Buttons);
//为工具栏加入按钮并显示在对话框中
return TRUE;
}
//当鼠标在工具栏上停留时,调用这个函数来显示提示信息
BOOL CToolBarInDialDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
TOOLTIPTEXT* tt;
tt=(TOOLTIPTEXT*)lParam;
CString Tip;
switch(tt->hdr.code)
{
case TTN_NEEDTEXT:
//该信息表明要求显示工具栏上的提示
switch(tt->hdr.idFrom)
{
case ID_PLAY:
Tip.LoadString(IDS_FIRST); //设置对应于工具栏上ID_PLAY的按钮的提示信息
break;
case ID_STOP:
Tip.LoadString(IDS_NEXT);
//IDS_FIRST,IDS_NEXT等为一系列CString串
break;
……//类似地设置剩下按钮的提示信息
}
strcpy(tt->szText,(LPCSTR)Tip);
//显示提示信息
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
//该演示程序的工具栏能由用户定制,随时增加或删除工具栏中的某一项
void CToolBarInDialDlg::OnApply()
{
switch(DoFlag) //用户选择了增加或删除工具栏中的“退出”按钮
{
case TRUE: //增加工具栏上的“退出”按钮
m_Buttons[ButtonCount].iBitmap=ButtonBitmap+ButtonCount;
m_Buttons[ButtonCount].idCommand=ID_QUIT;
m_Buttons[ButtonCount].fsState=TBSTATE_ENABLED;
m_Buttons[ButtonCount].fsStyle=TBSTYLE_BUTTON;
m_Buttons[ButtonCount].dwData=0;
m_Buttons[ButtonCount].iString=IDS_FIRST;
ToolBar.InsertButton(ButtonCount,&&m_Buttons[ButtonCount]);
//根据m_Buttons的信息在工具栏的尾部加上一个按钮
break;
case FALSE:
if(ToolBar.GetButtonCount()==4) //删除工具栏上某一特定位置的按钮
{
ToolBar.DeleteButton(3);
//删除工具栏上某一按钮
}
break;
}
}
void CToolBarInDialDlg::OnPlay() //响应函数举例
{
……
//对应选单项的响应函数
}