一直想不到合适的方法来解决孙鑫老师在第九课提出的问题:当工具栏在客户呈现浮动状态时,再次点击“新工具栏”按钮,会使工具栏重新放置在“工具栏”的下方。提示在CToolBar类或者它的父类中找到一些函数来解决该问题。查看MSDN发现CToolBar的父类为CControlBar,其中有两个成员函数FloatControlBar()和IsFloating()。只有你调用了FloatControlBar()后,IsFloating()才会返回TRUE,也就是说当你手动把“新工具栏”拖动到客户区时,虽然是呈现浮动状态,但是该函数的返回值仍然是FALSE。
后来自己想了一个方法:当“新工具栏”按钮添加成功后,在CMainFrame的OnCreate()中计算出“新工具栏”按钮与父窗口的间距dx和dy,再在OnNewtoolBar()函数中计算按钮与父窗口的间距DX和DY。根据DX与dx,DY与dy之间的比较,就可以判断“新工具栏”按钮是否移动了,移动到哪了?
环境:VS2008
步骤:1.资源视图的toolbar中添加一个工具栏,添加一些你想要的工具栏按钮,并在Menu中的视图下面添加一个“新 工具栏”按钮,ID为IDM_NEWTOOLBAR。
2.在CMainFrame中添加一个成员变量m_ToolBar,类型为CToolBar;
3.在OnCreate()函数中参照“工具栏”按钮的方法,添加“新工具栏按钮”;添加成员变量dx和dy,类型为int;添加成员变量rect_window和rect_toolbar,类型为CRect
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_ToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
m_ToolBar.EnableDocking(CBRS_ALIGN_TOP);
DockControlBar(&m_ToolBar);
GetMenu()->GetSubMenu(2)->CheckMenuItem(2,MF_BYPOSITION|MF_CHECKED);//设置复选标记
//获得初始化时“新工具栏”与父窗口的间距
m_ToolBar.GetWindowRect(&rect_toolbar);
GetWindowRect(&rect_window);
dx=rect_toolbar.left-rect_window.left;
dy=rect_toolbar.top-rect_window.top+24;
4.为“新工具栏”按钮添加消息响应函数OnNewtoolBar(),编辑代码
void CMainFrame::OnNewtoolbar()
{
// TODO: 在此添加命令处理程序代码
if(m_ToolBar.IsWindowVisible())
{
GetWindowRect(&rect_window);
m_ToolBar.GetWindowRect(&rect_toolbar);
m_ToolBar.ShowWindow(SW_HIDE);
DockControlBar(&m_ToolBar);
GetMenu()->GetSubMenu(2)->CheckMenuItem(2,MF_BYPOSITION|MF_UNCHECKED);
}
else
{
int DX=rect_toolbar.left-rect_window.left;
int DY=rect_toolbar.top-rect_window.top;
if(((DX>dx)&&(DY>dy))||(rect_toolbar.left-2<rect_window.left)||
(rect_toolbar.left>rect_window.right)||(rect_toolbar.bottom<rect_window.top))
{
CPoint point(rect_toolbar.left,rect_toolbar.top);
m_ToolBar.ShowWindow(SW_SHOW);
FloatControlBar(&m_ToolBar,point);
}
else
{
ScreenToClient(rect_toolbar);
m_ToolBar.MoveWindow(rect_toolbar);
m_ToolBar.ShowWindow(SW_SHOW);
}
GetMenu()->GetSubMenu(2)->CheckMenuItem(2,MF_BYPOSITION|MF_CHECKED);
}
RecalcLayout(TRUE);
//ShowControlBar(&m_ToolBar,!m_ToolBar.IsWindowVisible(),FALSE);
}
当(DX>dx)&&(DY>dy)时,表明“新工具栏”按钮是朝着右下方的位置移动,当rect_toolbar.left-2<rect_window.left,表面浮动的工具栏移出了父窗口,且在父窗口的左边,其他的类似。
剩下的情况表明窗口没有拖动成浮动状态,应该继续让其停留在该停留的位置。