📄 bcgpdockbarrow.cpp
字号:
int nMoveOffset = nOffset;
CRect rectBar; rectBar.SetRectEmpty ();
while (pos != NULL)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) (bForward ? m_lstControlBars.GetNext (pos)
: m_lstControlBars.GetPrev (pos));
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
ASSERT_VALID (pNextBar);
CRect rectNextBar;
pNextBar->GetWindowRect (rectNextBar);
if (pNextBar != pControlBar && !rectBar.IsRectEmpty ())
{
if (IsHorizontal ())
{
nMoveOffset -= bForward ? rectNextBar.left - rectBar.right
: rectNextBar.right - rectBar.left;
}
else
{
nMoveOffset -= bForward ? rectNextBar.top - rectBar.bottom
: rectNextBar.bottom - rectBar.top;
}
}
if (nMoveOffset <= 0 && bForward || nMoveOffset >= 0 && !bForward)
{
break;
}
rectBar = rectNextBar;
IsHorizontal () ? rectNextBar.OffsetRect (nMoveOffset, 0) : rectNextBar.OffsetRect (0, nMoveOffset);
m_pParentDockBar->ScreenToClient (rectNextBar);
pNextBar->SetWindowPos (NULL, rectNextBar.left, rectNextBar.top,
rectNextBar.Width (), rectNextBar.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
}
}
//**********************************************************************************************
void CBCGPDockBarRow::MoveControlBar (CBCGPControlBar* pControlBar, CPoint ptOffset,
BOOL bSwapControlBars, HDWP& hdwp)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectVirtual;
pControlBar->GetVirtualRect (rectVirtual);
CRect rectBarWnd;
pControlBar->GetWindowRect (&rectBarWnd);
CRect rectVirualNew = rectVirtual;
rectVirualNew.OffsetRect (ptOffset);
// the bar is being moved within the row, just move it horizontally or vertically
bool bForward = true;
CPoint ptMove (0, 0);
int nAllowedOffset = 0;
if (IsHorizontal ())
{
nAllowedOffset = ptMove.x = ptOffset.x;
bForward = (ptMove.x >= 0);
}
else
{
nAllowedOffset = ptMove.y = ptOffset.y;
bForward = (ptMove.y >= 0);
}
if (!IsEnoughSpaceToMove (pControlBar, bForward, nAllowedOffset))
{
return;
}
if (IsHorizontal () && abs (nAllowedOffset) < abs (ptMove.x))
{
ptMove.x = nAllowedOffset;
}
else if (!IsHorizontal () && abs (nAllowedOffset) < abs (ptMove.y))
{
ptMove.y = nAllowedOffset;
}
rectBarWnd.OffsetRect (ptMove);
if (CheckControlBars (rectBarWnd, pControlBar, bForward, ptMove, bSwapControlBars, hdwp))
{
m_pParentDockBar->ScreenToClient (&rectBarWnd);
pControlBar->SetWindowPos (NULL, rectBarWnd.left, rectBarWnd.top,
rectBarWnd.Width (), rectBarWnd.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
}
ArrangeBars (pControlBar);
}
//**********************************************************************************************
void CBCGPDockBarRow::MoveControlBar (CBCGPControlBar* pControlBar, CRect rectTarget, HDWP& hdwp)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectBarWnd;
pControlBar->GetWindowRect (&rectBarWnd);
if (IsHorizontal ())
{
rectBarWnd.left = rectTarget.left;
rectBarWnd.right = rectTarget.right;
}
else
{
rectBarWnd.top = rectTarget.top;
rectBarWnd.bottom = rectTarget.bottom;
}
m_pParentDockBar->ScreenToClient (&rectBarWnd);
pControlBar->SetWindowPos (NULL, rectBarWnd.left, rectBarWnd.top,
rectBarWnd.Width (), rectBarWnd.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
}
//**********************************************************************************************
void CBCGPDockBarRow::MoveControlBar (CBCGPControlBar* pControlBar, int nOffset, bool bForward, HDWP& hdwp)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
if (nOffset == 0)
{
return;
}
CRect rectBarWnd;
pControlBar->GetWindowRect (&rectBarWnd);
if (IsHorizontal ())
{
rectBarWnd.OffsetRect (bForward ? nOffset : -nOffset, 0);
}
else
{
rectBarWnd.OffsetRect (0, bForward ? nOffset : -nOffset);
}
m_pParentDockBar->ScreenToClient (&rectBarWnd);
pControlBar->SetWindowPos (NULL, rectBarWnd.left, rectBarWnd.top,
rectBarWnd.Width (), rectBarWnd.Height (),
SWP_NOZORDER | SWP_NOACTIVATE);
}
//**********************************************************************************************
void CBCGPDockBarRow::MoveControlBar (CBCGPControlBar* pControlBar, int nAbsolutOffset, HDWP& hdwp)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectBarWnd;
pControlBar->GetWindowRect (&rectBarWnd);
CRect rectRow;
GetWindowRect (rectRow);
int nBarLength = 0;
if (IsHorizontal ())
{
nBarLength = rectBarWnd.Width ();
rectBarWnd.left = rectRow.left + nAbsolutOffset;
rectBarWnd.right = rectBarWnd.left + nBarLength;
}
else
{
nBarLength = rectBarWnd.Height ();
rectBarWnd.top = rectRow.top + nAbsolutOffset;
rectBarWnd.bottom = rectBarWnd.top + nBarLength;
}
m_pParentDockBar->ScreenToClient (&rectBarWnd);
pControlBar->SetWindowPos (NULL, rectBarWnd.left, rectBarWnd.top,
rectBarWnd.Width (), rectBarWnd.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
}
//**********************************************************************************************
int CBCGPDockBarRow::GetVisibleCount ()
{
int nVisibleCount = 0;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!m_bIgnoreBarVisibility)
{
if (pNextBar->IsVisible ())
{
nVisibleCount++;
}
}
else
{
nVisibleCount++;
}
}
return nVisibleCount;
}
//**********************************************************************************************
BOOL CBCGPDockBarRow::CheckControlBars (CRect& rectCurrentBar, CBCGPControlBar* pCurrentBar,
bool bForward, CPoint ptOffset,
BOOL bSwapControlBars, HDWP& hdwp)
{
ASSERT_VALID (this);
if (m_lstControlBars.GetCount () < 2 ||
GetVisibleCount () < 2)
{
// nothing to check - there is only one control bar on the dock bar
return TRUE;
}
CRect rectNextControlBar;
CRect rectNextControlBarVirt;
CBCGPControlBar* pNextBar = NULL;
CRect rectIntersect;
BOOL bIntersect = FALSE;
POSITION posCurrentBar = m_lstControlBars.Find (pCurrentBar);
// position of the bar which intersects with the current bar
POSITION posIntersect = NULL;
// find a control bar which whill intersect with the current bar
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
posIntersect = pos;
pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
if (pNextBar != pCurrentBar)
{
ASSERT_VALID (pNextBar);
pNextBar->GetWindowRect (&rectNextControlBar);
bIntersect = rectIntersect.IntersectRect (rectNextControlBar, rectCurrentBar);
if (bIntersect)
{
break;
}
}
}
if (!bIntersect || pNextBar == NULL)
{
// the current bar does not intersect with any bar on the row, check whether
// we need to move "trailing bars" - whose virtual rectangle is out of place
MoveTrailingBars (posCurrentBar, ptOffset, bForward, pCurrentBar, hdwp);
return TRUE;
}
// get the virtual rectangle of the bar that intersects with the curr. bar
pNextBar->GetVirtualRect (rectNextControlBarVirt);
// if the current bar has just crossed a point when it is no more on the left side
// from the virtual rect (when moving forward), or it is no more on the right side
// when moving backward;
// the next control bar should be transferred to the opposite side
CRect rectIntersectVirt;
if (rectIntersectVirt.IntersectRect (rectNextControlBarVirt, rectCurrentBar) && bSwapControlBars)
{
if (bForward && pCurrentBar->IsLeftOf (rectNextControlBarVirt) ||
!bForward && !pCurrentBar->IsLeftOf (rectNextControlBarVirt))
{
CRect rectNew = rectNextControlBar;
if (IsHorizontal ())
{
bForward ? rectNew.right = rectCurrentBar.left
: rectNew.left = rectCurrentBar.right ;
bForward ? rectNew.left = rectNew.right - rectNextControlBar.Width ()
: rectNew.right = rectNew.left + rectNextControlBar.Width ();
}
else
{
bForward ? rectNew.bottom = rectCurrentBar.top
: rectNew.top = rectCurrentBar.bottom;
bForward ? rectNew.top = rectNew.bottom - rectNextControlBar.Height ()
: rectNew.bottom = rectNew.top + rectNextControlBar.Height ();
}
MoveControlBar (pNextBar, rectNew, hdwp);
m_lstControlBars.RemoveAt (posIntersect);
bForward ? m_lstControlBars.InsertBefore (posCurrentBar, pNextBar) :
m_lstControlBars.InsertAfter (posCurrentBar, pNextBar);
ResolveIntersection (pNextBar, !bForward, hdwp);
// now we need to shift all control bars behind pNextBar to make them closer
// to the current bar
CRect rectWnd;
CRect rectVirt;
bForward ? m_lstControlBars.GetNext (posCurrentBar) : m_lstControlBars.GetPrev (posCurrentBar);
for (POSITION pos = posCurrentBar; pos != NULL;)
{
CBCGPControlBar* pMovedBar = (CBCGPControlBar*)
(bForward ? m_lstControlBars.GetNext (pos) : m_lstControlBars.GetPrev (pos));
ASSERT_VALID (pMovedBar);
if (!pMovedBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pMovedBar->GetWindowRect (&rectWnd);
pMovedBar->GetVirtualRect (rectVirt);
if (rectWnd != rectVirt)
{
int nOffset = IsHorizontal () ? rectNew.Width () : rectNew.Height ();
nOffset -= IsHorizontal () ? abs (ptOffset.x) : abs (ptOffset.y);
MoveControlBar (pMovedBar, nOffset, !bForward, hdwp); // move in opposite direction
}
}
return TRUE;
}
}
int nMoveOffset = IsHorizontal () ? rectIntersect.Width () : rectIntersect.Height ();
MoveControlBar (pNextBar, nMoveOffset, bForward, hdwp);
ResolveIntersection (pNextBar, bForward, hdwp);
MoveTrailingBars (posCurrentBar, ptOffset, bForward, pCurrentBar, hdwp);
return TRUE;
}
//**********************************************************************************************
void CBCGPDockBarRow::MoveTrailingBars (POSITION posStart, CPoint ptOffset, bool bForward,
CBCGPControlBar* pBarToSkip, HDWP& hdwp)
{
ASSERT_VALID (this);
CRect rectNextControlBar;
CRect rectNextControlBarVirt;
for (POSITION pos = posStart; pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) (bForward ? m_lstControlBars.GetPrev (pos) : m_lstControlBars.GetNext (pos));
ASSERT_VALID (pNextBar);
if (pNextBar == pBarToSkip)
{
continue;
}
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pNextBar->GetWindowRect (&rectNextControlBar);
pNextBar->GetVirtualRect (rectNextControlBarVirt);
if (rectNextControlBar != rectNextControlBarVirt)
{
int nOffsetToMove = 0;
if (bForward && pNextBar->IsLeftOf (rectNextControlBarVirt) ||
!bForward && !pNextBar->IsLeftOf (rectNextControlBarVirt))
{
nOffsetToMove = IsHorizontal () ? abs (ptOffset.x) : abs (ptOffset.y);
}
else if (bForward && !pNextBar->IsLeftOf (rectNextControlBarVirt) ||
!bForward && pNextBar->IsLeftOf (rectNextControlBarVirt))
{
if (IsHorizontal ())
{
nOffsetToMove = min (abs (ptOffset.x),
abs (rectNextControlBarVirt.left - rectNextControlBar.left));
}
else
{
nOffsetToMove = min (abs (ptOffset.y),
abs (rectNextControlBarVirt.top - rectNextControlBar.top));
}
}
MoveControlBar (pNextBar, nOffsetToMove, bForward, hdwp);
ResolveIntersection (pNextBar, !bForward, hdwp);
}
}
}
//**********************************************************************************************
void CBCGPDockBarRow::ResolveIntersection (CBCGPControlBar* pBar, bool bForward, HDWP& hdwp)
{
ASSERT_VALID (this);
ASSERT_VALID (pBar);
POSITION posStart = m_lstControlBars.Find (pBar);
CRect rectBarWnd;
rectBarWnd.SetRectEmpty ();
CRect rectRowWnd;
GetWindowRect (rectRowWnd);
CRect rectIntersect;
CRect rectMovedBar;
for (POSITION pos = posStart; pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*)
(bForward ? m_lstControlBars.GetNext (pos) : m_lstControlBars.GetPrev (pos));
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pNextBar->GetWindowRect (&rectBarWnd);
CBCGPControlBar* pMovedBar = NULL;
POSITION posSave = NULL;
for (POSITION posMoved = pos; posMoved != NULL;)
{
posSave = posMoved;
pMovedBar = (CBCGPControlBar*)
(bForward ? m_lstControlBars.GetNext (posMoved) : m_lstControlBars.GetPrev (posMoved));
if (pMovedBar->IsVisible () || m_bIgnoreBarVisibility)
{
break;
}
}
if (pMovedBar == NULL)
{
break;
}
pMovedBar->GetWindowRect (&rectMovedBar);
if (bForward &&
(IsHorizontal () && rectMovedBar.left > rectBarWnd.right ||
!IsHorizontal () && rectMovedBar.top > rectBarWnd.bottom) ||
!bForward &&
(IsHorizontal () && rectMovedBar.right < rectBarWnd.left ||
!IsHorizontal () && rectMovedBar.bottom < rectBarWnd.top))
{
pos = posSave;
continue;
}
int nMoveOffset = 0;
if (bForward)
{
nMoveOffset = IsHorizontal () ? rectBarWnd.right - rectMovedBar.left
: rectBarWnd.bottom - rectMovedBar.top;
}
else
{
nMoveOffset = IsHorizontal () ? rectMovedBar.right - rectBarWnd.left
: rectMovedBar.bottom - rectBarWnd.top;
}
MoveControlBar (pMovedBar, nMoveOffset, bForward, hdwp);
pos = posSave;
}
}
//**********************************************************************************************
BOOL CBCGPDockBarRow::IsEnoughSpaceToMove (CBCGPControlBar* pControlBar, bool bForward, int& nAllowedOffset)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
int nLen = 0;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CRect rectBar;
CBCGPControlBar* pBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pBar);
if (!pBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pBar->GetWindowRect (&rectBar);
if (pBar == pControlBar)
{
continue;
}
if (bForward && !pControlBar->IsLeftOf (rectBar) ||
!bForward && pControlBar->IsLeftOf (rectBar))
{
IsHorizontal () ? nLen += rectBar.Width () : nLen += rectBar.Height ();
}
}
CRect rectControlBar;
pControlBar->GetWindowRect (&rectControlBar);
CRect rectRow;
GetWindowRect (rectRow);
nAllowedOffset = 0;
if (IsHorizontal ())
{
nAllowedOffset = bForward ? rectRow.right - rectControlBar.right :
rectRow.left - rectControlBar.left;
}
else
{
nAllowedOffset = bForward ? rectRow.bottom - rectControlBar.bottom :
rectRow.top - rectControlBar.top;
}
nAllowedOffset = bForward ? nAllowedOffset - nLen : nAllowedOffset + nLen;
if (bForward && nAllowedOffset <= 0 ||
!bForward && nAllowedOffset >= 0)
{
return FALSE;
}
return TRUE;
}
//**********************************************************************************************
void CBCGPDockBarRow::OffsetFromRect (const CRect& rect, CPoint& pt, bool bForward)
{
switch (m_dwRowAlignment & CBRS_ALIGN_ANY)
{
case CBRS_ALIGN_TOP:
case CBRS_ALIGN_BOTTOM:
bForward ? pt.x = rect.Width () : pt.x = -rect.Width ();
break;
case CBRS_ALIGN_LEFT:
case CBRS_ALIGN_RIGHT:
bForward ? pt.y = rect.Height () : pt.y = -rect.Height ();
break;
}
}
//**********************************************************************************************
void CBCGPDockBarRow::FixupVirtualRects (bool bMoveBackToVirtualRect, CBCGPControlBar* pBarToExclude)
{
ASSERT_VALID (this);
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -