void CMDIFrameWndEx::RecalcLayout()
{
...
m_dockManager.RecalcLayout(bNotify)
{
...
for (pos = m_lstControlBars.GetHeadPosition(); pos != NULL;)
{
CBasePane* pNextControlBar = (CBasePane*) m_lstControlBars.GetNext(pos);
pNextControlBar->AdjustLayout();
}
for (pos = m_lstMiniFrames.GetHeadPosition(); pos != NULL;)
{
CPaneFrameWnd* pNextMiniFrame = (CPaneFrameWnd*) m_lstMiniFrames.GetNext(pos);
pNextMiniFrame->AdjustLayout();
}
...
AdjustDockingLayout()
{
...
m_pParentWnd->GetClientRect(rectCurrBounds);
...
for (pos = m_lstControlBars.GetHeadPosition(); pos != NULL;)
{
posBar = pos;
CBasePane* pNextControlBar = (CBasePane*) m_lstControlBars.GetNext(pos);
//得到控件条窗口的CRect.
pNextControlBar->GetWindowRect(rectControlBar);
CRect rectSave = rectControlBar;
DWORD dwAlignment = pNextControlBar->GetCurrentAlignment();
BOOL bHorizontal = pNextControlBar->IsHorizontal();
BOOL bResizable = pNextControlBar->IsResizable();
//计算控件条所需大小
CSize sizeRequered = pNextControlBar->CalcFixedLayout(FALSE, bHorizontal);
//调整控件条的CRect.
if (bHorizontal)
{
dwAlignment & CBRS_ALIGN_TOP ? rectControlBar.bottom = rectControlBar.top + sizeRequered.cy : rectControlBar.top = rectControlBar.bottom - sizeRequered.cy;
}
else
{
dwAlignment & CBRS_ALIGN_LEFT ? rectControlBar.right = rectControlBar.left + sizeRequered.cx : rectControlBar.left = rectControlBar.right - sizeRequered.cx;
}
//在客户区窗口rectCurrBounds中排列控件,并得到窗口位置大小rectControlBar等
AlignByRect(rectCurrBounds, rectControlBar, dwAlignment, bHorizontal, bResizable);
CRect rectControlBarScreen = rectControlBar;
//根据窗口位置大小rectControlBar移动窗口
if (pNextControlBar->IsKindOf(RUNTIME_CLASS(CDockSite)))
{
pNextControlBar->ScreenToClient(rectControlBar);
if (pNextControlBar->IsHorizontal() && rectControlBar.Width() > 0 || !pNextControlBar->IsHorizontal() && rectControlBar.Height() > 0)
{
((CDockSite*) pNextControlBar)->RepositionPanes(rectControlBar);
}
rectControlBar = rectControlBarScreen;
}
if (pNextControlBar->IsKindOf(RUNTIME_CLASS(CPaneDivider)))
{
// the slider will change its position, as well as position of
// its resizable control bars(container)
((CPaneDivider*) pNextControlBar)->RepositionPanes(rectControlBar, hdwp);
}
else
{
pNextControlBar->GetParent()->ScreenToClient(rectControlBar);
hdwp = pNextControlBar->SetWindowPos(NULL, rectControlBar.left, rectControlBar.top, rectControlBar.Width(), rectControlBar.Height(), SWP_NOZORDER | SWP_NOACTIVATE, hdwp);
}
//减去控件件条的布置位置后,调整客户区窗口的位置大小等rectCurrBounds。
if (dwAlignment & CBRS_ALIGN_TOP)
{
rectCurrBounds.top += rectControlBarScreen.Height();
}
else if (dwAlignment & CBRS_ALIGN_BOTTOM)
{
rectCurrBounds.bottom -= rectControlBarScreen.Height();
}
else if (dwAlignment & CBRS_ALIGN_LEFT)
{
rectCurrBounds.left += rectControlBarScreen.Width();
}
else
{
rectCurrBounds.right -= rectControlBarScreen.Width();
}
if (posLastDockBar == pos)
{
m_rectOuterEdgeBounds = rectCurrBounds;
}
}
}
...
}
//利用rectCurrBounds设置位置
AdjustClientArea()
{
//1、单文档如下:
CWnd* pChildWnd = GetDlgItem(AFX_IDW_PANE_FIRST);
pChildWnd->SetWindowPos(&wndBottom, rectClientAreaBounds.left, rectClientAreaBounds.top, rectClientAreaBounds.Width(), rectClientAreaBounds.Height(), SWP_NOACTIVATE);
//2、多文档如下:
m_wndClientArea.CalcWindowRect(rectCurrBounds, 0)
{
SetWindowPos(NULL, rectCurrBounds->left, rectCurrBounds->top, rectCurrBounds->right - rectCurrBounds->left, rectCurrBounds->bottom - lpClientRect->top, SWP_NOZORDER | SWP_NOACTIVATE);
}
...
}