Anneke Sicherer
May 21st, 1999, 10:13 AM
Hello all,
I do know how to dock toolbars side by side. What I am desperate about is that I cannot find a way e.g. in OnSize, to make sure every toolbar is visible. If the toolbar would fall off of the left side of
the window it should be the first one docked on the next line.
The code I use is below. The idea is to undock all toolbars and dock them one after the other side by side until the next one would be outside the window. Then start docking them on the next line and so on.
Stepping through this code shows that I do correctly compute all toolbar positions, but they still show up at the wrong places. Sometimes nearly all below each other and sometimes still falling of the right edge. I have been struggling with this for more that a week.
Can anybody help please?!?
Does anyone have code to achieve this correctly?
void MyFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
ShuffleToolbars();
}
void MyFrameWnd::ShuffleToolbars()
{
// get size of frame window
CRect outerRect;
GetWindowRect(&outerRect);
// create sorted array of toolbar pointers
CTypedPtrArray<CObArray, CToolBar*> BarArray;
CWordArray widthArray;
CDockBar *pDockBar = (CDockBar*)GetControlBar(AFX_IDW_DOCKBAR_TOP);
ASSERT(pDockBar &&
((CWnd*)pDockBar)->IsKindOf(RUNTIME_CLASS(CDockBar))); for (CWnd
*pWnd = pDockBar->GetTopWindow(); pWnd; pWnd =
pWnd->GetNextWindow()) {
if ((pWnd->GetStyle() & WS_VISIBLE) &&
pWnd->IsKindOf(RUNTIME_CLASS(CToolBar))) {
CRect thisRect;
pWnd->GetWindowRect(&thisRect);
int i;
for (i = 0; i < BarArray.GetSize(); ++i) {
CRect otherRect;
BarArray[i]->GetWindowRect(&otherRect);
if (otherRect.top > thisRect.top ||
otherRect.top == thisRect.top && otherRect.left >
thisRect.left)
break;
}
BarArray.InsertAt(i, (CToolBar*)pWnd);
widthArray.InsertAt(i, thisRect.Width());
}
}
for (int j = 0; j < BarArray.GetSize(); ++j) {
char title[100]; BarArray[j]->GetWindowText(title,100);
TRACE("%30s %5d\n",title, BarArray[j]->m_hWnd);
}
// determine topleft position for first toolbar
CRect thisRect;
BarArray[0]->GetWindowRect(&thisRect);
int toolbarLeft = thisRect.left + 1;
int toolbarTop = thisRect.top + 1;
int toolbarHeight = thisRect.Height();
// undock all toolbars
for (int i = 0; i < BarArray.GetSize(); i++) {
FloatControlBar(BarArray[i], CPoint(0,0));
}
// compute new positions of toolbars and dock them
int xpos = toolbarLeft;
int row = 0;
int ypos = toolbarTop;
CToolBar *pLeftBar = NULL;
for (i = 0; i < BarArray.GetSize(); i++) {
CToolBar *pBar = BarArray[i];
if (xpos + widthArray[i] > outerRect.right) { // start next row
xpos = toolbarLeft;
ypos = toolbarTop + (row + 1) * toolbarHeight - 2;
++row;
}
CRect rect;
rect.left = xpos;
rect.top = ypos;
rect.right = rect.left + widthArray[i];
rect.bottom = rect.top + toolbarHeight;
xpos += widthArray[i] - 2;
DockControlBar(pBar, AFX_IDW_DOCKBAR_TOP, &rect);
}
}
I do know how to dock toolbars side by side. What I am desperate about is that I cannot find a way e.g. in OnSize, to make sure every toolbar is visible. If the toolbar would fall off of the left side of
the window it should be the first one docked on the next line.
The code I use is below. The idea is to undock all toolbars and dock them one after the other side by side until the next one would be outside the window. Then start docking them on the next line and so on.
Stepping through this code shows that I do correctly compute all toolbar positions, but they still show up at the wrong places. Sometimes nearly all below each other and sometimes still falling of the right edge. I have been struggling with this for more that a week.
Can anybody help please?!?
Does anyone have code to achieve this correctly?
void MyFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
ShuffleToolbars();
}
void MyFrameWnd::ShuffleToolbars()
{
// get size of frame window
CRect outerRect;
GetWindowRect(&outerRect);
// create sorted array of toolbar pointers
CTypedPtrArray<CObArray, CToolBar*> BarArray;
CWordArray widthArray;
CDockBar *pDockBar = (CDockBar*)GetControlBar(AFX_IDW_DOCKBAR_TOP);
ASSERT(pDockBar &&
((CWnd*)pDockBar)->IsKindOf(RUNTIME_CLASS(CDockBar))); for (CWnd
*pWnd = pDockBar->GetTopWindow(); pWnd; pWnd =
pWnd->GetNextWindow()) {
if ((pWnd->GetStyle() & WS_VISIBLE) &&
pWnd->IsKindOf(RUNTIME_CLASS(CToolBar))) {
CRect thisRect;
pWnd->GetWindowRect(&thisRect);
int i;
for (i = 0; i < BarArray.GetSize(); ++i) {
CRect otherRect;
BarArray[i]->GetWindowRect(&otherRect);
if (otherRect.top > thisRect.top ||
otherRect.top == thisRect.top && otherRect.left >
thisRect.left)
break;
}
BarArray.InsertAt(i, (CToolBar*)pWnd);
widthArray.InsertAt(i, thisRect.Width());
}
}
for (int j = 0; j < BarArray.GetSize(); ++j) {
char title[100]; BarArray[j]->GetWindowText(title,100);
TRACE("%30s %5d\n",title, BarArray[j]->m_hWnd);
}
// determine topleft position for first toolbar
CRect thisRect;
BarArray[0]->GetWindowRect(&thisRect);
int toolbarLeft = thisRect.left + 1;
int toolbarTop = thisRect.top + 1;
int toolbarHeight = thisRect.Height();
// undock all toolbars
for (int i = 0; i < BarArray.GetSize(); i++) {
FloatControlBar(BarArray[i], CPoint(0,0));
}
// compute new positions of toolbars and dock them
int xpos = toolbarLeft;
int row = 0;
int ypos = toolbarTop;
CToolBar *pLeftBar = NULL;
for (i = 0; i < BarArray.GetSize(); i++) {
CToolBar *pBar = BarArray[i];
if (xpos + widthArray[i] > outerRect.right) { // start next row
xpos = toolbarLeft;
ypos = toolbarTop + (row + 1) * toolbarHeight - 2;
++row;
}
CRect rect;
rect.left = xpos;
rect.top = ypos;
rect.right = rect.left + widthArray[i];
rect.bottom = rect.top + toolbarHeight;
xpos += widthArray[i] - 2;
DockControlBar(pBar, AFX_IDW_DOCKBAR_TOP, &rect);
}
}