www.gusucode.com > 又一VC++酒店管理软件的源码源码程序 > 又一VC++酒店管理软件的源码/hotel2003/hotel2003/CoolControlBar.cpp

    /*########################################################################
	Filename: 	CoolControlbar.cpp
	----------------------------------------------------
	Remarks:	...
	----------------------------------------------------
	Author:		成真
	Email:		anyou@sina.com
				anyou@msn.com
	Created:	7/3/2003 21:52
  ########################################################################*/
#include "stdafx.h"
#include "resource.h"
#include "CoolControlBar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CCoolBarArray CCoolControlBar::m_arrBars; 

/*########################################################################
			  ------------------------------------------------
								  class CCoolControlBar
			  ------------------------------------------------
  ########################################################################*/

CCoolControlBar::CCoolControlBar()
{
	m_bTracking = FALSE;
	m_bParentSizing = FALSE;
}

CCoolControlBar::~CCoolControlBar()
{

}

BOOL CCoolControlBar::Create(CWnd *pParentWnd, CSize size, UINT dwStyle, UINT uID)
{
	ASSERT_VALID(pParentWnd);
	ASSERT( (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_TOP    ||
			(dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_BOTTOM ||
			(dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_LEFT   ||
			(dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_RIGHT);
	
    ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
	
	m_dwStyle = (dwStyle & CBRS_ALL);
	// keep only the generic window styles--------------
	dwStyle &= ~CBRS_ALL;
	// force WS_CLIPSIBLINGS (otherwise will cause repaint problems)---
	dwStyle |= WS_CLIPSIBLINGS;
	
	BOOL bRets = CControlBar::Create(NULL, NULL, dwStyle, 
		CRect(0, 0, 0, 0), pParentWnd, uID, NULL);
	if (bRets)
	{
		m_szDefault = size;    
		m_szHorz	= size;
		m_szVert	= size;
		m_szFloat   = size;
		
		// force the size to zero - resizing bar will occur later----------
		SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
	}
	return bRets;
}

BOOL CCoolControlBar::DestroyWindow() 
{
    int nPos = FindCoolBar(this);
    ASSERT(nPos >= 0);
    m_arrBars.RemoveAt(nPos);
	
	return CControlBar::DestroyWindow();
}

CSize CCoolControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
	if (bStretch) 
	{
		return CSize(bHorz ? 32767 : m_szVert.cx, bHorz ? m_szHorz.cy : 32767);
	}
	else
	{
		// dirty cast - using CCoolDockBar to access protected CDockBar members
		CFriendDockBar* pDockBar = (CFriendDockBar*)m_pDockBar;
		if (pDockBar != NULL)
		{
			// force imediate RecalcDelayShow() for all sizing bars on the row
			// with delayShow/delayHide flags set to avoid IsVisible() problems
			CCoolBarArray arrCoolBars;
			GetCoolBars(arrCoolBars);
			AFX_SIZEPARENTPARAMS layout;
			layout.hDWP = pDockBar->m_bLayoutQuery ? NULL 
				: ::BeginDeferWindowPos(arrCoolBars.GetSize());
			for (int i = 0; i < arrCoolBars.GetSize(); i++)
			{
				arrCoolBars[i]->RecalcDelayShow(&layout);
			}
			
			if (layout.hDWP != NULL)
			{
				::EndDeferWindowPos(layout.hDWP);
			}
			if (IsVisible() && !IsFloating() && m_bParentSizing && arrCoolBars[0] == this)
			{
				m_bParentSizing = FALSE;

				CRect rc = pDockBar->m_rectLayout;
				if (rc.IsRectEmpty())
				{
					m_pDockSite->GetClientRect(&rc);
				}
				
				int nLengthAvail = bHorz ? rc.Width() + 2 : rc.Height();
				if (AutoSize(nLengthAvail, bHorz))
				{
					AutoAlign();
				}
			}
		}
		return bHorz ? m_szHorz : m_szVert;
	}
}

CSize CCoolControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
	if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
    {
		if (nLength == -1) m_bParentSizing = TRUE;
        return CControlBar::CalcDynamicLayout(nLength, dwMode);
    }

    if (dwMode & LM_MRUWIDTH) return m_szFloat;
    if (dwMode & LM_COMMIT)   return m_szFloat; // already committed

    ((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength;

    m_szFloat.cx = max(m_szFloat.cx, m_szDefault.cx);
    m_szFloat.cy = max(m_szFloat.cy, m_szDefault.cy);

   return m_szFloat;
}

IMPLEMENT_DYNAMIC(CCoolControlBar, CControlBar);

/*########################################################################
			  ------------------------------------------------
								Message handlers
			  ------------------------------------------------
  ########################################################################*/

BEGIN_MESSAGE_MAP(CCoolControlBar, CControlBar)
//{{AFX_MSG_MAP(CCoolControlBar)
	ON_WM_NCCALCSIZE()
	ON_WM_NCPAINT()
	ON_WM_ERASEBKGND()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_WINDOWPOSCHANGING()
	ON_WM_NCHITTEST()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_NCLBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

int CCoolControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    m_arrBars.Add(this);
	if (CControlBar::OnCreate(lpCreateStruct) == -1)
	{
		return -1;
	}
	return 0;
}

void CCoolControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
	// force non-client recalc if moved or resized
    lpwndpos->flags |= SWP_FRAMECHANGED;
	CControlBar::OnWindowPosChanging(lpwndpos);
}

void CCoolControlBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
	CRect rect = lpncsp->rgrc[0];

	BOOL bALignLeft   = (m_dwStyle & CBRS_ALIGN_LEFT  );
	BOOL bALignRight  = (m_dwStyle & CBRS_ALIGN_RIGHT );
	BOOL bALignTop    = (m_dwStyle & CBRS_ALIGN_TOP   );
	BOOL bALignBottom = (m_dwStyle & CBRS_ALIGN_BOTTOM);

	if ((m_dwStyle & CBRS_FLOATING) != CBRS_FLOATING)
	{
		if (m_pDockBar != NULL)
		{
			rect.DeflateRect(5, 5);
		}
		else
		{
			if (bALignLeft) rect.DeflateRect(1, 1, 3, 0);
			else if (bALignRight) rect.DeflateRect(3, 0, 1, 0);
			else if (bALignTop) rect.DeflateRect(0, 0, 0, 3);
			else rect.DeflateRect(0, 3, 0, 0);
		}

		if (m_dwStyle & CBRS_TITLEBAR)
		{
			(IsHorizontal() ? rect.left : rect.top) += 16;
		}
	}

    lpncsp->rgrc[0] = rect;	
}

void CCoolControlBar::OnNcPaint() 
{
    CWindowDC dc(this);
	dc.SetBkMode(TRANSPARENT);
	
    CRect rcClient, rcWindow;
    GetWindowRect(&rcWindow);
    GetClientRect(&rcClient);
	ClientToScreen(&rcClient);
    rcClient.OffsetRect(-rcWindow.TopLeft());
    rcWindow.OffsetRect(-rcWindow.TopLeft());

	//填充背景-----------------------------------------
	if (rcClient.bottom > rcClient.top && rcClient.right > rcClient.left)
	{
		 dc.ExcludeClipRect(rcClient);
	}
	dc.FillSolidRect(rcWindow, ::GetSysColor(COLOR_3DFACE));
	
	//绘制边框-----------------------------------------
	if (m_pDockBar != NULL)
	{
		dc.Draw3dRect(rcWindow, RGB(128, 128, 128), RGB(255, 255, 255));
		rcWindow.DeflateRect(1, 1);
		dc.Draw3dRect(rcWindow, RGB(255, 255, 255), RGB(128, 128, 128));
	}
	
	//绘制标题栏---------------------------------------
	if (m_dwStyle & CBRS_TITLEBAR)
	{
		CRect rcTitleBar(rcWindow);
		if (IsHorizontal())
		{
			rcTitleBar.right = rcTitleBar.left + 19;
			rcTitleBar.DeflateRect(0, 4);
			if (m_pDockBar == NULL)
			{
				rcTitleBar.OffsetRect(-2, 0);
			}

			m_rcCloseButton.right = rcTitleBar.right - 1;
			m_rcCloseButton.top   = rcTitleBar.top + 1;
		}
		else
		{
			rcTitleBar.bottom = rcTitleBar.top + 19;
			rcTitleBar.DeflateRect(4, 0);
			if (m_pDockBar == NULL)
			{
				rcTitleBar.OffsetRect(0, -2);
			}
			m_rcCloseButton.right = rcTitleBar.right - 1;
			m_rcCloseButton.top   = rcTitleBar.top + 4;
		}
		m_rcCloseButton.left = m_rcCloseButton.right - 12;
		m_rcCloseButton.bottom = m_rcCloseButton.top + 12;

		DrawTitleBar(&dc, rcTitleBar, IsHorizontal());
		DrawCloseButton(&dc, m_dwButtonState);
	}
	
	ReleaseDC(&dc);
}

void CCoolControlBar::OnPaint() 
{
	CPaintDC dc(this); 
}

BOOL CCoolControlBar::OnEraseBkgnd(CDC* pDC) 
{
	CRect rect;
	GetClientRect(&rect);
	pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
	return CControlBar::OnEraseBkgnd(pDC);
}

UINT CCoolControlBar::OnNcHitTest(CPoint point) 
{
	if (IsFloating())
	{
		return CControlBar::OnNcHitTest(point);
	}

    CRect rcWindow, rcTrack;
    GetWindowRect(rcWindow);

	if (m_dwStyle & CBRS_TITLEBAR)
	{
		CRect rc(m_rcCloseButton);
		rc.OffsetRect(rcWindow.TopLeft());
		if (rc.PtInRect(point))
		{
			return HTCLOSE;
		}
	}
	
	for (int i = 0; i < 4; i++)
	{
		if (GetTrackRect(rcTrack, i) && rcTrack.PtInRect(point)) 
		{
			switch (i) 
			{
				case 0:  return HTLEFT;	  break;
				case 1:  return HTTOP; 	  break;
				case 2:  return HTRIGHT;  break;
				case 3:  return HTBOTTOM; break;
			}
		}
	}
	
	return HTCLIENT; 
}

void CCoolControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
	if (IsFloating())
	{
		CControlBar::OnNcLButtonDown(nHitTest, point);
		return;
	}
	
	if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
	{
		SetCapture();
		m_bTracking  = TRUE;
		m_bTrackType = nHitTest;
		m_oldPoint   = point;
	}
}

void CCoolControlBar::OnNcLButtonUp(UINT nHitTest, CPoint point) 
{
	if (nHitTest == HTCLOSE)
	{
		GetParentFrame()->ShowControlBar(this, FALSE, FALSE);
		return;
	}	
	CControlBar::OnNcLButtonUp(nHitTest, point);
}

void CCoolControlBar::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_bTracking)
	{
		ClientToScreen(&point);
		UpdateWndSize(point);
	}
	CControlBar::OnMouseMove(nFlags, point);
}

void CCoolControlBar::OnLButtonUp(UINT nFlags, CPoint point) 
{
	ReleaseCapture();
	if (m_bTracking)
	{
		m_bTracking = FALSE;
		return;
	}
	CControlBar::OnLButtonUp(nFlags, point);
}

void CCoolControlBar::OnUpdateCmdUI(CFrameWnd *pTarget, BOOL bDisableIfNoHndler)
{
	CPoint point;
    ::GetCursorPos(&point);
	CRect rcWindow;
	GetWindowRect(&rcWindow);
	point = point - rcWindow.TopLeft();

	DWORD dwoldState = m_dwButtonState;
	m_dwButtonState = m_rcCloseButton.PtInRect(point) ?
				((::GetKeyState(VK_LBUTTON) < 0) ? 2 : 1) : 0;
	// if need paint---------------------------------------
    if (dwoldState != m_dwButtonState)
	{
        SendMessage(WM_NCPAINT);
	}	
}

/*########################################################################
			  ------------------------------------------------
						
			  ------------------------------------------------
  ########################################################################*/

BOOL CCoolControlBar::GetTrackRect(CRect& rcTrack, int nEdge)
{
	CRect rcWindow;
    GetWindowRect(rcWindow);
    rcTrack = rcWindow;
	
	BOOL bAtStart = TRUE;
	BOOL bAtEnd   = TRUE;

	if (m_pDockBar != NULL)
	{
		CCoolBarArray arrCoolBars;
		GetCoolBars  (arrCoolBars);
		bAtStart  =  (arrCoolBars[0] == this);
		bAtEnd    =  (arrCoolBars[arrCoolBars.GetSize() - 1] == this);
	}

	BOOL bALignLeft   = (m_dwStyle & CBRS_ALIGN_LEFT  );
	BOOL bALignRight  = (m_dwStyle & CBRS_ALIGN_RIGHT );
	BOOL bALignTop    = (m_dwStyle & CBRS_ALIGN_TOP   );
	BOOL bALignBottom = (m_dwStyle & CBRS_ALIGN_BOTTOM);
	
    BOOL bHorz = IsHorizontal();
	
    switch (nEdge)
    {
	case 0:
		{
			if (!bALignRight) return FALSE;
			rcTrack.right = rcTrack.left + SIZING_WIDTH;
		}
		break;
	case 1:
		{
			if (!bALignBottom) return FALSE;
			rcTrack.bottom = rcTrack.top + SIZING_WIDTH;
		}
		break;
	case 2:
		{
			if (bALignRight || (bAtEnd && (bALignTop || bALignBottom))) return FALSE;
			rcTrack.left = rcTrack.right - SIZING_WIDTH;
		}
		break;
	case 3:
		{
			if (bALignBottom || (bAtEnd && (bALignLeft || bALignRight))) return FALSE;
			rcTrack.top = rcTrack.bottom - SIZING_WIDTH;
		}
		break;
    default:
        ASSERT(FALSE); // invalid hit test code
    }
    return TRUE;
}

void CCoolControlBar::UpdateWndSize(CPoint point)
{
	ASSERT(m_bTracking);
	if (!m_bTracking) return;
	BOOL bHorz = IsHorizontal();
	
	CSize szOld = (bHorz ? m_szHorz : m_szVert);
	CSize szNew = szOld;

	//仅在控制栏所在的行内改变大小--------------------------
	if ((m_bTrackType == HTRIGHT && bHorz) || (m_bTrackType == HTBOTTOM && !bHorz))
	{
		CCoolBarArray arrCoolBars;
		GetCoolBars(arrCoolBars);
		//取得与它相邻的下一条控制条的指针------------------
		for (int i = 0; i < arrCoolBars.GetSize(); i++)
		{
			if (arrCoolBars.GetAt(i) == this) break;
		}
		CCoolControlBar *pCoolBar = arrCoolBars.GetAt(i + 1);

		if (bHorz)
		{
			if ((m_szHorz.cx == TITLE_HEIGHT && (point.x < m_oldPoint.x))
				|| (pCoolBar->m_szHorz.cx == TITLE_HEIGHT && (point.x > m_oldPoint.x))) 
			{
				return;
			}
			m_szHorz.cx += (point.x - m_oldPoint.x);
			pCoolBar->m_szHorz.cx -= (point.x - m_oldPoint.x);
			
			if (m_szHorz.cx < TITLE_HEIGHT)
			{
				pCoolBar->m_szHorz.cx += m_szHorz.cx - TITLE_HEIGHT;
				m_szHorz.cx = TITLE_HEIGHT;
			}
			else if (pCoolBar->m_szHorz.cx < TITLE_HEIGHT)
			{
				m_szHorz.cx -= TITLE_HEIGHT - pCoolBar->m_szHorz.cx;
				pCoolBar->m_szHorz.cx = TITLE_HEIGHT;
			}
			AutoAlign();
		}
		else
		{
			if ((m_szVert.cy == TITLE_HEIGHT && (point.y < m_oldPoint.y))
			 || (pCoolBar->m_szVert.cy == TITLE_HEIGHT && (point.y > m_oldPoint.y))) 
			{
				return;
			}
			m_szVert.cy += (point.y - m_oldPoint.y);
			pCoolBar->m_szVert.cy -= (point.y - m_oldPoint.y);
			
			if (m_szVert.cy < TITLE_HEIGHT)
			{
				pCoolBar->m_szVert.cy += m_szVert.cy - TITLE_HEIGHT;
				m_szVert.cy = TITLE_HEIGHT;
			}
			else if (pCoolBar->m_szVert.cy < TITLE_HEIGHT)
			{
				m_szVert.cy -= TITLE_HEIGHT - pCoolBar->m_szVert.cy;
				pCoolBar->m_szVert.cy = TITLE_HEIGHT;
			}
			AutoAlign();
		}

		m_oldPoint = point;
		return;
	}

	switch (m_bTrackType) 
	{
		case HTLEFT:   szNew.cx -= (point.x - m_oldPoint.x); break;
		case HTRIGHT:  szNew.cx += (point.x - m_oldPoint.x); break;
		case HTTOP:	   szNew.cy -= (point.y - m_oldPoint.y); break;
		case HTBOTTOM: szNew.cy += (point.y - m_oldPoint.y); break;
		default: return; break;
	}
	//取得可用的最大尺寸---------------------------------
	CRect rc;
	m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST, reposQuery, &rc, NULL, TRUE);
    CSize szMax = szOld + rc.Size() - CSize(4, 4);

	//限制它的最小和最大尺寸-----------------------------	
	szNew.cx = max(TITLE_HEIGHT, min(szNew.cx, szMax.cx));
	szNew.cy = max(TITLE_HEIGHT, min(szNew.cy, szMax.cy));

	//是否改变了尺寸-------------------------------------
	if ((szNew.cx - szOld.cx) == 0 && (szNew.cy - szOld.cy) == 0) return;

	(bHorz ? m_szHorz : m_szVert) = szNew;
	m_pDockSite->DelayRecalcLayout();
	m_oldPoint = point;
}

int CCoolControlBar::GetFirstBar()
{
	ASSERT_VALID(m_pDockBar); 
    int nThis = m_pDockBar->FindBar(this);
    ASSERT(nThis != -1);
	
    // find the first bar in row
    for (int i = nThis - 1; i >= 0; i--)
	{
        if (m_pDockBar->m_arrBars[i] == NULL)
		{
			return(i + 1);
		}
	}
    ASSERT(FALSE);
	return -1;
}

int CCoolControlBar::GetLastBar()
{
	ASSERT_VALID(m_pDockBar); 
    int nThis = m_pDockBar->FindBar(this);
    ASSERT(nThis != -1);
	
    int nBarsCount = m_pDockBar->m_arrBars.GetSize();
	
    // find the last bar in row
    for (int i = nThis + 1; i < nBarsCount; i++)
	{
        if (m_pDockBar->m_arrBars[i] == NULL)
		{
            return(i - 1);
		}
	}
    ASSERT(FALSE);
	return -1;
}

void CCoolControlBar::GetCoolBars(CCoolBarArray &arrCoolBars)
{
	ASSERT_VALID(m_pDockBar); 
	
    arrCoolBars.RemoveAll();

	int nFirst = GetFirstBar();
	int nLast  = GetLastBar();
    for (int i = nFirst; i <= nLast; i++)
    {
        CControlBar* pBar = (CControlBar*)m_pDockBar->m_arrBars[i];
        if (HIWORD(pBar) == 0)  continue; // placeholder
        if (!pBar->IsVisible()) continue;
        if (FindCoolBar(pBar) >= 0)
		{
            arrCoolBars.Add((CCoolControlBar*)pBar);
		}
    }
}

int CCoolControlBar::FindCoolBar(CControlBar *pBar)
{
   for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
   {
        if (m_arrBars[nPos] == pBar)
		{
            return nPos; // got it
		}
   }
    return -1; // not found
}

/*========================================================================
	Params:		
		nLengthAvail:	此行中所有控制条共有的有用的长度
		bHorz:			控制条停泊方向
    ----------------------------------------------------------
	returns:	
    ----------------------------------------------------------
	Remarks:	自动分配各控制条的尺寸
==========================================================================*/
BOOL CCoolControlBar::AutoSize(int nLengthAvail, BOOL bHorz)
{
	CCoolBarArray  arrCoolBars;
    GetCoolBars(arrCoolBars);
    CCoolControlBar *pCoolBar = NULL;
	
    int nActualLength = 0;
    int nWidth = 0, nSizingWidth = 0;

	int nFirst = GetFirstBar();
	int nLast  = GetLastBar();

	// 减去可见的固定长度的控制栏的长度
    // subtract the visible fixed bars' lengths-----------------
    for (int i = nFirst; i <= nLast; i++)
    {
        CControlBar* pFixedBar = (CControlBar*)m_pDockBar->m_arrBars[i];
        if (HIWORD(pFixedBar) == 0) 
		{
			continue; // 占位符(placeholder)
		}
        else if (!pFixedBar->IsVisible() || FindCoolBar(pFixedBar) >= 0) 
		{
			continue; // 不可见或不是固定控制栏.
		}
		
		CRect rcBarWindow;
        pFixedBar->GetWindowRect(&rcBarWindow);
        nLengthAvail -= (bHorz ? rcBarWindow.Width() - 2 : rcBarWindow.Height() - 2);
    }
	
	// 计算实际长度以及公共宽度.
    // compute actual and min lengths; also the common width----
    for (i = 0; i < arrCoolBars.GetSize(); i++)
    {
        pCoolBar = arrCoolBars[i];
        nActualLength += bHorz ? pCoolBar->m_szHorz.cx - 2 : pCoolBar->m_szVert.cy - 2;
        nWidth = max(nWidth, bHorz ? pCoolBar->m_szHorz.cy : pCoolBar->m_szVert.cx);
		
		if (pCoolBar->m_bTracking)
		{	
			//如果此控制栏正在被用户改变大小----------------------------
			//if this control bar is sizing now-------------------------
			nSizingWidth = bHorz ? pCoolBar->m_szHorz.cy: pCoolBar->m_szVert.cx;
		}
    }

	//如果其中有控制栏在改变大小,则公共宽度为当前正在改变宽度的控制栏的
	//宽度,否则为当前栏中,宽度最大的那条控制栏的宽度------------------
	if (nSizingWidth > 0)
	{
		nWidth = nSizingWidth;
	}
    
	// 使所有的控制栏具有相同的宽度.
    // make the bars same width---------------------------------
	for (i = 0; i < arrCoolBars.GetSize(); i++)
	{
        (bHorz ? arrCoolBars[i]->m_szHorz.cy : arrCoolBars[i]->m_szVert.cx) = nWidth;
	}

	// no change------------------------------------------------
    if (nActualLength == nLengthAvail)
	{
        return FALSE; 
	}
	
    int nLengthDelta = nLengthAvail - nActualLength - 2;
	int nCount = arrCoolBars.GetSize();
	int bSizingBar = -1;
	int nlength = 0;

	//查看有否有控制栏处于拖动中----------------------------
	for (i = 0; i < nCount; i++)
	{
		if (arrCoolBars[i]->m_bTracking)
		{
			if ((!arrCoolBars[i]->IsHorizontal() && (arrCoolBars[i]->m_bTrackType == HTLEFT || arrCoolBars[i]->m_bTrackType == HTRIGHT))
			  || (arrCoolBars[i]->IsHorizontal() && (arrCoolBars[i]->m_bTrackType == HTTOP  || arrCoolBars[i]->m_bTrackType == HTBOTTOM)))
			{
				return FALSE;
			}
			bSizingBar = i;
			break;
		}
	}
	
	// 分配各控制栏尺寸.
    // distribute the difference between the bars, but-----------
    // don't shrink them below minsize
	BOOL bChangeDefaultSize = FALSE;
	while (nLengthDelta != 0)
	{
		BOOL bDefaultSize = TRUE;
		BOOL bMinSize = TRUE;
		
		for (i = 0; i < nCount; i++)
		{
			pCoolBar = arrCoolBars[i];
			int nLenght = bHorz ? pCoolBar->m_szHorz.cx : pCoolBar->m_szVert.cy;

			if (nLenght == TITLE_HEIGHT && nLengthDelta < 0) // already at min length--
			{
				continue;
			}
			
			bMinSize = FALSE;

			if (nLenght < m_szDefault.cy && nLengthDelta < 0 && !bChangeDefaultSize) // already at default length--
			{
				continue;
			}
			
			// sign of nLengthDelta-------------------------------------------
			(bHorz ? pCoolBar->m_szHorz.cx : pCoolBar->m_szVert.cy) += nLengthDelta / abs(nLengthDelta);
			nLengthDelta -= nLengthDelta / abs(nLengthDelta);
			bDefaultSize = FALSE;
			if (nLengthDelta == 0) break;

		}// end for
		
		if (bMinSize)	return FALSE;
		bChangeDefaultSize = bDefaultSize;

	}// end while
    return TRUE;
}

void CCoolControlBar::AutoAlign()
{
	int nFirst = GetFirstBar();
	int nLast  = GetLastBar();
	
    BOOL bHorz = (m_dwStyle & (CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM));
	
    //是否需要重新调整-------------------------------
	BOOL bNeedRecalc = FALSE;
    int nPos, nAlign = bHorz ? -2 : 0;

    CRect rcControlWnd, rcDockWnd;
    m_pDockBar->GetWindowRect(&rcDockWnd);

    for (int i = nFirst; i <= nLast; i++)
    {
        CControlBar* pControlBar = (CControlBar*)m_pDockBar->m_arrBars[i];
		//placeholder-----------------------------
		if (HIWORD(pControlBar) == 0) 		continue;
		//it's not visible------------------------
        else if (!pControlBar->IsVisible()) continue;
		
		//Get rect and offset---------------------
        pControlBar->GetWindowRect(&rcControlWnd);
        rcControlWnd.OffsetRect(-rcDockWnd.TopLeft());

		//Is CCoolControlBar----------------------
        if ((nPos = FindCoolBar(pControlBar)) >= 0)
		{
            rcControlWnd = CRect(rcControlWnd.TopLeft(), bHorz ?
                m_arrBars[nPos]->m_szHorz : m_arrBars[nPos]->m_szVert);
		}

		
		//Align-----------------------------------
        if ((bHorz ? rcControlWnd.left : rcControlWnd.top) != nAlign)
        {
            if (!bHorz)
			{
                rcControlWnd.OffsetRect(0, nAlign - rcControlWnd.top -2);
			}
            else
			{
                rcControlWnd.OffsetRect(nAlign - rcControlWnd.left, -2);
			}
            pControlBar->MoveWindow(rcControlWnd);
            bNeedRecalc = TRUE;
        }
        nAlign += (bHorz ? rcControlWnd.Width() - 2 : rcControlWnd.Height() - 2);
    }
	
	//if need recalc-------------------------------
    if (bNeedRecalc)
    {
        m_pDockSite->DelayRecalcLayout();
    }
}

inline BOOL CCoolControlBar::IsHorizontal()
{
    return (m_dwStyle & (CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM));
}

/*####################################################################
			------------------------------------------------
					 Load / Save controlbar states
			------------------------------------------------
  ####################################################################*/

void CCoolControlBar::LoadState(LPCTSTR lpszProfileName)
{
    ASSERT_VALID(this);
    ASSERT(GetSafeHwnd() != NULL); // must be called after Create()

    CWinApp* pApp = AfxGetApp();

    TCHAR szSection[256];
    wsprintf(szSection, _T("%s\\CoolControlBar(%d)"), lpszProfileName, GetDlgCtrlID());

    m_szHorz.cx  = (int)pApp->GetProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
    m_szHorz.cy  = (int)pApp->GetProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);

    m_szVert.cx  = (int)pApp->GetProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
    m_szVert.cy  = (int)pApp->GetProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);

    m_szFloat.cx = (int)pApp->GetProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
    m_szFloat.cy = (int)pApp->GetProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
}

void CCoolControlBar::SaveState(LPCTSTR lpszProfileName)
{
    // place your SaveState or GlobalSaveState call in
    // CMainFrame::DestroyWindow(), not in OnDestroy()
    ASSERT_VALID(this);
    ASSERT(GetSafeHwnd() != NULL);

    CWinApp* pApp = AfxGetApp();

    TCHAR szSection[256];
    wsprintf(szSection, _T("%s\\CoolControlBar(%d)"), lpszProfileName, GetDlgCtrlID());

    pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
    pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);

    pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
    pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);

    pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
    pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
}

void CCoolControlBar::LoadStates(LPCTSTR lpszProfileName)
{
    for (int i = 0; i < m_arrBars.GetSize(); i++)
	{
        ((CCoolControlBar*) m_arrBars[i])->LoadState(lpszProfileName);
	}
}

void CCoolControlBar::SaveStates(LPCTSTR lpszProfileName)
{
    for (int i = 0; i < m_arrBars.GetSize(); i++)
	{
        ((CCoolControlBar*) m_arrBars[i])->SaveState(lpszProfileName);
	}
}

/*########################################################################
			  ------------------------------------------------
							   绘制标题栏函数
			  ------------------------------------------------
  ########################################################################*/

void CCoolControlBar::DrawTitleBar(CDC *pDC, const CRect &rect, BOOL bHorz)
{
	CRect rcTitleBar(rect);
	CPen pen(0, 1, ::GetSysColor(COLOR_3DSHADOW));
	CPen *oldpen = pDC->SelectObject(&pen);
	pDC->SetTextColor(RGB(0, 0, 0));
	CString strWindowText;
	GetWindowText(strWindowText);
	
	if (bHorz)
	{
		CFont font, *oldfont;
		font.CreateFont(-12,0,900,0,400,0,0,0,0,0,0,0,0,"宋体");
		oldfont = pDC->SelectObject(&font);
		pDC->TextOut(rcTitleBar.left + 3, rcTitleBar.bottom - 3, strWindowText);
		pDC->FillSolidRect(4, 2, 14, 16, ::GetSysColor(COLOR_3DFACE));
		pDC->SelectObject(&oldfont);
		rcTitleBar.DeflateRect(2, -1, 1, -1);
		pDC->Draw3dRect(rcTitleBar, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
	}
	else
	{
		rcTitleBar.DeflateRect(-1, 2, -1, 1);
		pDC->Draw3dRect(rcTitleBar, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
		CFont font, *oldfont;
		font.CreateFont(-12,0,0,0,400,0,0,0,0,0,0,0,0,"宋体");
		oldfont = pDC->SelectObject(&font);

		rcTitleBar.DeflateRect(5, 0, 15, 0);

		pDC->DrawText(strWindowText, rcTitleBar, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
		pDC->SelectObject(oldfont);
	}
	pDC->SelectObject(oldpen);
}

void CCoolControlBar::DrawCloseButton(CDC *pDC, DWORD dwState)
{
	//hot-----------------------
	if (dwState == 1)
	{
		pDC->FillSolidRect(m_rcCloseButton, RGB(225,225,255));
		pDC->Draw3dRect(m_rcCloseButton, RGB(80,80,100), RGB(80,80,100));
	}
	//pressed--------------------
	else if(dwState == 2)
	{
		pDC->FillSolidRect(m_rcCloseButton, RGB(130,150,200));
		pDC->Draw3dRect(m_rcCloseButton, RGB(80,80,100), RGB(80,80,100));
		pDC->SelectStockObject(WHITE_PEN);
	}
	//draw 'x' sign---------------------------------------
	pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 3);
	pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 9);
	pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 8);
	pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 2);
	
	pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 4);
	pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 10);
	pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 9);
	pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 3);
	
	pDC->SelectStockObject(BLACK_PEN);
}