www.pudn.com > clking_src.rar > GuiDocBarExten.cpp


//-----------------------------------------------------------------------// 
// This is a part of the GuiLib MFC Extention.							 //	 
// Autor  :  Francisco Campos											 // 
// (C) 2002 Francisco Campos  All 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; 
}