工具栏(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() //响应函数举例

  {

  ……

  //对应选单项的响应函数

  }

  以上程序在中/英文Windows 98、VC++ 6.0环境下编译通过,运行正常。图2为运行中的有工具栏的对话框程序。