www.pudn.com > clking_src.rar > GuiDocBarExten.cpp
//-----------------------------------------------------------------------// // This is a part of the GuiLib MFC Extention. // // Autor : Francisco Campos // // (C) 2002 Francisco CamposAll rights reserved // // This code is provided "as is", with absolutely no warranty expressed // // or implied. Any use is at your own risk. // // You must obtain the author's consent before you can include this code // // in a software library. // // If the source code in this file is used in any application // // then acknowledgement must be made to the author of this program // // fcampos@tutopia.com // //-----------------------------------------------------------------------// #include "stdafx.h" #include "GuiToolBarWnd.h" #include "GuiDocBarExten.h" #include "MenuBar.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CGuiDocBarExten,CDockBar) BEGIN_MESSAGE_MAP(CGuiDocBarExten,CDockBar) //{{AFX_MSG_MAP(CGuiDocBarExten) //}}AFX_MSG_MAP END_MESSAGE_MAP() CGuiDocBarExten::CGuiDocBarExten() { } CGuiDocBarExten::~CGuiDocBarExten() { } ///////////////////////////////////////////////////////////////////////////// // CDockBarEx message handlers void CGuiDocBarExten::BarsDocking(CFrameWnd * pFrame, DWORD dwDockStyle) { ASSERT_VALID(pFrame); // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0); pFrame->EnableDocking(dwDockStyle); for (int i = 0; i < 4; i++) { if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY) { CDockBar* pDock = (CDockBar*)pFrame->GetControlBar(dwDockBarMap[i][0]); if( pDock == 0 || ! pDock->IsKindOf(RUNTIME_CLASS(CGuiDocBarExten)) ) { BOOL bNeedDelete = ! pDock->m_bAutoDelete; pDock->m_pDockSite->RemoveControlBar(pDock); pDock->m_pDockSite = 0; pDock->DestroyWindow(); if( bNeedDelete ) delete pDock; pDock = 0; } if( pDock == 0 ) { pDock = new CGuiDocBarExten; ASSERT_VALID(pDock); if ((!pDock) || (!pDock->Create(pFrame, WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE | dwDockBarMap[i][1], dwDockBarMap[i][0]))) { AfxThrowResourceException(); } } } } } CSize CGuiDocBarExten::CalcFixedLayout(BOOL bStretch, BOOL bHorz) { ASSERT_VALID(this); CSize sizeFixed = CControlBar::CalcFixedLayout(bStretch, bHorz); // get max size CSize sizeMax; if (!m_rectLayout.IsRectEmpty()) { CRect rect = m_rectLayout; CalcInsideRect(rect, bHorz); sizeMax = rect.Size(); } else { CRect rectFrame; CFrameWnd* pFrame = GetParentFrame(); pFrame->GetClientRect(&rectFrame); sizeMax = rectFrame.Size(); } // prepare for layout AFX_SIZEPARENTPARAMS layout; layout.hDWP = m_bLayoutQuery ? NULL : ::BeginDeferWindowPos(m_arrBars.GetSize()); int cxBorder = 2, cyBorder = 2; CPoint pt(-cxBorder, -cyBorder); int nWidth = 0; BOOL bWrapped = FALSE; // layout all the control bars for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++) { CControlBar* pBar = GetDockedControlBar(nPos); void* pVoid = m_arrBars[nPos]; if (pBar != NULL) { if(pBar->IsKindOf(RUNTIME_CLASS(CGuiToolBarWnd)) || pBar->IsKindOf(RUNTIME_CLASS(CMenuBar)) ) cxBorder = cyBorder = 0; else cxBorder = cyBorder = 2; if (pBar->IsVisible()) { // get ideal rect for bar DWORD dwMode = 0; if ((pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) && (pBar->m_dwStyle & CBRS_FLOATING)) dwMode |= LM_HORZ | LM_MRUWIDTH; else if (pBar->m_dwStyle & CBRS_ORIENT_HORZ) dwMode |= LM_HORZ | LM_HORZDOCK; else dwMode |= LM_VERTDOCK; CSize sizeBar = pBar->CalcDynamicLayout(-1, dwMode); CRect rect(pt, sizeBar); // get current rect for bar CRect rectBar; pBar->GetWindowRect(&rectBar); ScreenToClient(&rectBar); if (bHorz) { // Offset Calculated Rect out to Actual if (rectBar.left > rect.left && !m_bFloating) rect.OffsetRect(rectBar.left - rect.left, 0); // If ControlBar goes off the right, then right justify if (rect.right > sizeMax.cx && !m_bFloating) { int x = rect.Width() - cxBorder; x = max(sizeMax.cx - x, pt.x); rect.OffsetRect(x - rect.left, 0); } // If ControlBar has been wrapped, then left justify if (bWrapped) { bWrapped = FALSE; rect.OffsetRect(-(rect.left + cxBorder), 0); } // If ControlBar is completely invisible, then wrap it else if ((rect.left >= (sizeMax.cx - cxBorder)) && (nPos > 0) && (m_arrBars[nPos - 1] != NULL)) { m_arrBars.InsertAt(nPos, (CObject*)NULL); pBar = NULL; pVoid = NULL; bWrapped = TRUE; } if (!bWrapped) { if (rect != rectBar) { if (!m_bLayoutQuery && !(pBar->m_dwStyle & CBRS_FLOATING)) { pBar->m_pDockContext->m_rectMRUDockPos = rect; } AfxRepositionWindow(&layout, pBar->m_hWnd, &rect); } pt.x = rect.left + sizeBar.cx - cxBorder; nWidth = max(nWidth, sizeBar.cy); } } else { // Offset Calculated Rect out to Actual if (rectBar.top > rect.top && !m_bFloating) rect.OffsetRect(0, rectBar.top - rect.top); // If ControlBar goes off the bottom, then bottom justify if (rect.bottom > sizeMax.cy && !m_bFloating) { int y = rect.Height() - cyBorder; y = max(sizeMax.cy - y, pt.y); rect.OffsetRect(0, y - rect.top); } // If ControlBar has been wrapped, then top justify if (bWrapped) { bWrapped = FALSE; rect.OffsetRect(0, -(rect.top + cyBorder)); } // If ControlBar is completely invisible, then wrap it else if ((rect.top >= (sizeMax.cy - cyBorder)) && (nPos > 0) && (m_arrBars[nPos - 1] != NULL)) { m_arrBars.InsertAt(nPos, (CObject*)NULL); pBar = NULL; pVoid = NULL; bWrapped = TRUE; } if (!bWrapped) { if (rect != rectBar) { if (!m_bLayoutQuery && !(pBar->m_dwStyle & CBRS_FLOATING)) { pBar->m_pDockContext->m_rectMRUDockPos = rect; } AfxRepositionWindow(&layout, pBar->m_hWnd, &rect); } pt.y = rect.top + sizeBar.cy - cyBorder; nWidth = max(nWidth, sizeBar.cx); } } } if (!bWrapped) { // handle any delay/show hide for the bar pBar->RecalcDelayShow(&layout); } } if (pBar == NULL && pVoid == NULL && nWidth != 0) { // end of row because pBar == NULL if (bHorz) { pt.y += nWidth - cyBorder; sizeFixed.cx = max(sizeFixed.cx, pt.x); sizeFixed.cy = max(sizeFixed.cy, pt.y); pt.x = -cxBorder; } else { pt.x += nWidth - cxBorder; sizeFixed.cx = max(sizeFixed.cx, pt.x); sizeFixed.cy = max(sizeFixed.cy, pt.y); pt.y = -cyBorder; } nWidth = 0; } } if (!m_bLayoutQuery) { // move and resize all the windows at once! if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP)) { TRACE0("Warning: DeferWindowPos failed - low system resources.\n"); } } // adjust size for borders on the dock bar itself CRect rect; rect.SetRectEmpty(); CalcInsideRect(rect, bHorz); if ((!bStretch || !bHorz) && sizeFixed.cx != 0) sizeFixed.cx += -rect.right + rect.left; if ((!bStretch || bHorz) && sizeFixed.cy != 0) sizeFixed.cy += -rect.bottom + rect.top; return sizeFixed; }