VC:控制工具条的停靠位置

鬼谷子
VC:控制工具条的停靠位置
  在VC5 中开发大型应用程序时,工具条通常是程序中必不可少的重要功能因素,其中工具条在整个窗口中的
停靠位置尤其关键,它直接影响到程序界面的外观形象。下面针对笔者实际开发中各类工具条停靠位置的控制过
程,详细阐述其实现技巧。
  一、标准工具条停靠位置的控制
  VC5 应用程序向导生成的框架代码中,都具有普通工具条的控制方法。正常情况下工具条类CToolBar是控
制条类CControlBar 的派生类,其显示的初始停靠位置是通过调用继承的函数CControlBar::EnableDocking
(DWORD dwStyle)来确定的,其参数dwStyle用来指定停靠具体位置,与本文有关的风格如下(其余请参阅
VC5的联机文档):
  CBRS_ALIGN_TOP 停靠在框架窗口客户区域顶部
  CBRS_ALIGN_BOTTOM 停靠在框架窗口客户区域底部
  CBRS_ALIGN_LEFT 停靠在框架窗口客户区域左边
  CBRS_ALIGN_RIGHT 停靠在框架窗口客户区域右边
  CBRS_ALIGN_ANY 停靠在框架窗口客户区域任何位置
  在利用应用程序向导AppWizard 生成的应用程序中,其控制代码默认的停靠位置控制风格为
CBRS_ALIGN_ANY,即允许停靠在框架窗口客户区域的任何边上。工具条在正常显示时为停靠在窗口客户区域
的顶部,控制指令为EnableDocking(CBRS_ALIGN_ANY)或m_wndToolBar。EnableDocking
(CBRS_ALIGN_ANY) ,注意,在实际程序控制时前者必须处于所有其它控制代码的前面,否则浮动工具条或特
殊工具条等部分代码可能无法奏效。具体控制方法请参考利用应用程序向导生成的任何一个程序实例的框架代码部
分中的建立函数ONCREATE()。
  应用程序的单文档和多文档的窗口框架类均为CFrameWnd 的派生类,其指定工具条的停靠位置均是通过调
用继承的函数 CFrameWnd::EnableDocking(DWORD dwDockStyle)来实现的,其可选的参数除上述五种
之外,还增加了CBRS_FLOAT_MULTI参数,这个参数主要是为设计浮动工具条而增加的,其用来确定一个框架
窗口中允许存在多个浮动工具条。同样,利用应用程序向导AppWizard 生成的应用程序,其默认的停靠位置也是
CBRS_ALIGN_ANY,即允许工具条停靠在框架窗口的任何边上,其默认的初始位置为框架窗口的顶部,即为
EnableDocking(CBRS_ALIGN_ANY)或m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY)。
  二、浮动工具条停靠位置的控制
  如果在一个框架窗口中存在多个标准或浮动工具条时,需要利用函数void DockControlBar(CControlBar
*pBar,UINT nDockBarID=0,LPCRECT lpRect= NULL)来确定要控制停靠位置的工具条,它也是
CFrameWnd类的成员函数,其中参数pBar用来指向被控制停靠位置的工具条对象指针,参数nDockBarID用来
确定工具条停靠在框架窗口的哪条边上,其控制风格的具体取值为:
  AFX_IDW_DOCKBAR_TOP 停靠在框架窗口的顶部
  AFX_IDW_DOCKBAR_BOTTOM 停靠在框架窗口的底部
  AFX_IDW_DOCKBAR_LEFT 停靠在框架窗口的左边
  AFX_IDW_DOCKBAR_RIGHT 停靠在框架窗口的右边
  当参数nDockBarID的取值为0时,则工具条可以停靠在框架窗口中的任何一个可停靠的边上,其默认的初始
位置为窗口顶部。
  三、并列工具条停靠位置的控制
  很多大型应用程序中都存在这样的工具条,将多个工具条同时并列停靠在某窗口的某一条边上。对于这种停靠
方法,利用上述工具条控制函数DockControlBar的lpRect参数,通过控制工具条的停靠矩形区域的方法可以实
现。如笔者实现的函数如下:
  (一)在实现文件MainFrm.h中增加如下成员函数定义
  void DockControlBarLeftOf(CToolBar* Bar,CToolBar* LeftOf);
  (二)在实现文件MainFrm.cpp中增加如下成员函数
  void CMainFrame::DockControlBarLeftOf(CToolBar* Bar,CToolBar* LeftOf)
   { //设置工具条并列停靠在同一条边上
   CRect rect; //矩形区域定义
   DWORD dw;
   UINT n=0;
   RecalcLayout();//重新显示
   LeftOf->GetWindowRect(&rect);
   rect.OffsetRect(1,0);//设置偏移值以停靠在同一边上
   dw=LeftOf->GetBarStyle();
   n=(dw&CBRS_ALIGN_TOP)?AFX_IDW_DOCKBAR_TOP:n;
   n=(dw&CBRS_ALIGN_BOTTOM&&n==0)?AFX_IDW_DOCKBAR_BOTTOM:n;
   n=(dw&CBRS_ALIGN_LEFT&&n==0)?AFX_IDW_DOCKBAR_LEFT:n;
   n=(dw&CBRS_ALIGN_RIGHT&&n==0)?AFX_IDW_DOCKBAR_RIGHT:n;
   DockControlBar(Bar,n,&rect);
   }
  在这个函数中应注意对RecalcLayout()函数和OffsetRect()函数的调用,前一个函数用来重新显示被调整的
客户区和工具条,后一个函数用来重新确定矩形区域,这相当于利用鼠标将第二个工具条窗口拖动到前一个工具条
上然后释放。
  (三)修改应用程序建立函数OnCreate()中的相应DockControlBar()函数为DoctControlBarOf()函数,
并正确设置工具条对象的指针,如笔者实现程序中的控制代码如下:
  EnableDocking(CBRS_ALIGN_ANY);//停靠位置必须在最前面
   ......//工具条建立函数
   m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
   m_wndTestToolBar.EnableDocking(CBRS_ALIGN_ANY);
   DockControlBar(&m_wndToolBar,AFX_IDW_DOCKBAR_TOP);
   //使两个工具条并列停靠
   DockControlBarLeftOf(&m_wndTestToolBar,&m_wndToolBar);
  四、工具条顶部停靠位置的控制
  工具条的最后一种停靠位置控制方法是,如何控制定制工具条的停靠位置,如具有通用控制功能工具条的停靠
位置等。这主要实现左右两侧定制工具条与顶部工具条之间谁靠近框架窗口边的位置关系。如笔者实现程序中的控
制步骤如下:
  (一)打开菜单资源增加顶部位置控制菜单项IDD_DLGBARTOP;
  (二)在实现文件MainFrm.h中增加成员控制变量m_bDialogTop;
   BOOL m_bDialogTop;
   并在构造函数中为其设置初始值;
  (三)利用类向导ClassWizard为菜单项设置响应函数;
  (四)在实现文件MainFrm.cpp中通过充分利用SetWindowPos( )成员完善消息映射功能。
   void CMainFrame::OnButtonDlgbartop()
   { //定制工具条顶部位置控制函数
   if (m_bDialogTop) m_wndDlgBar.SetWindowPos(
   &m_wndStatusBar,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
   //顶部工具条停靠在窗口边,左右工具条停靠其下
   else m_wndDlgBar.SetWindowPos(&wndTop,0,0,0,0,
   SWP_NOSIZE|SWP_NOMOVE);//停靠在最顶部
   RecalcLayout(); //重新显示窗口
   m_bDialogTop=!m_bDialogTop;//改变变量标志
   }
   void CMainFrame::OnUpdateButtonDlgbartop(CCmdUI* pCmdUI)
   { //设置菜单项检查状态更新函数
   pCmdUI->SetCheck(m_bDialogTop);
   }
  这样,就可以利用菜单项来控制定制工具条的顶部停靠位置。

龙丘居士亦可怜
谈空说有夜不眠
忽闻河东师子吼
拄杖落手心茫然