www.pudn.com > AccessADO.rar > 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);
}