📄 bcgpdockbarrow.cpp
字号:
{
continue;
}
if (pNextBar == pBarToExclude)
{
continue;
}
CRect rectBarWnd;
pNextBar->GetWindowRect (&rectBarWnd);
if (bMoveBackToVirtualRect)
{
CRect rectVirtual;
pNextBar->GetVirtualRect (rectVirtual);
if (rectVirtual != rectBarWnd)
{
HDWP hdwp = BeginDeferWindowPos (m_lstControlBars.GetCount ());
MoveControlBar (pNextBar, rectVirtual, hdwp);
EndDeferWindowPos (hdwp);
}
}
else
{
pNextBar->UpdateVirtualRect ();
}
}
}
//**********************************************************************************************
int CBCGPDockBarRow::GetAvailableLength (BOOL bUseVirtualRect) const
{
ASSERT_VALID (this);
CRect rectRow;
GetClientRect (rectRow);
int nTotalBarLength = 0;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
CRect rectWnd;
bUseVirtualRect ? pNextBar->GetVirtualRect (rectWnd) : pNextBar->GetWindowRect (&rectWnd);
nTotalBarLength += IsHorizontal () ? rectWnd.Width () : rectWnd.Height ();
}
// debug variable
int nAvailableLength = IsHorizontal () ? rectRow.Width () - nTotalBarLength :
rectRow.Height () - nTotalBarLength;
return nAvailableLength;
}
//**********************************************************************************************
int CBCGPDockBarRow::GetMaxBarSize (BOOL bSkipHiddenBars) const
{
ASSERT_VALID (this);
int nMaxSize = 0;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && bSkipHiddenBars && !m_bIgnoreBarVisibility)
{
continue;
}
CRect rectWnd;
pNextBar->GetWindowRect (&rectWnd);
nMaxSize = max (nMaxSize, IsHorizontal () ? rectWnd.Height () : rectWnd.Width ());
}
// don't use extra space if there are no visible bars
if (nMaxSize != 0)
{
nMaxSize += m_nExtraSpace;
}
return nMaxSize;
}
//**********************************************************************************************
void CBCGPDockBarRow::GetAvailableSpace (CRect& rect)
{
ASSERT_VALID (this);
GetWindowRect (rect);
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
CRect rectWnd;
pNextBar->GetWindowRect (&rectWnd);
IsHorizontal () ? rect.DeflateRect (rectWnd.Width (), 0) :
rect.DeflateRect (0, rectWnd.Height ());
}
}
//**********************************************************************************************
void CBCGPDockBarRow::ArrangeControlBars (int nMargin, int nSpacing)
{
CRect rectRow;
CRect rectBar;
CPoint ptOffset (0, 0);
GetWindowRect (rectRow);
bool bFistBar = true;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pBar);
if (!pBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pBar->GetWindowRect (rectBar);
if (bFistBar)
{
IsHorizontal () ? ptOffset.x = rectRow.left + nMargin :
ptOffset.y = rectRow.top + nMargin;
bFistBar = false;
}
if (!pBar->m_bFirstInGroup)
{
IsHorizontal () ? ptOffset.x -= (nSpacing + CBCGPAutoHideButton::m_nBorderSize):
ptOffset.y -= (nSpacing + + CBCGPAutoHideButton::m_nBorderSize);
}
int nLen = 0;
if (IsHorizontal ())
{
int nWidth = rectBar.Width ();
rectBar.left = ptOffset.x;
rectBar.right = rectBar.left + nWidth;
nLen = nWidth;
}
else
{
int nHeight = rectBar.Height ();
rectBar.top = ptOffset.y;
rectBar.bottom = rectBar.top + nHeight;
nLen = nHeight;
}
ScreenToClient (rectBar);
pBar->SetWindowPos (NULL, rectBar.left, rectBar.top,
rectBar.Width (), rectBar.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
pBar->StretchControlBar (nLen, !IsHorizontal ());
// get the rect after stretch
pBar->GetWindowRect (rectBar);
IsHorizontal () ? ptOffset.x += rectBar.Width () + nSpacing :
ptOffset.y += rectBar.Height () + nSpacing;
}
}
//**********************************************************************************************
void CBCGPDockBarRow::ArrangeBars (CBCGPControlBar* pInitialBar)
{
ASSERT_VALID (this);
if (m_lstControlBars.IsEmpty ())
{
return;
}
CRect rectRow;
GetClientRect (rectRow);
if (rectRow.IsRectEmpty ())
{
// the row still is not initialized
return;
}
HDWP hdwp = NULL;
int nAvailLength = GetAvailableLength ();
// handle single bar
if (m_lstControlBars.GetCount () == 1)
{
if (pInitialBar == NULL)
{
pInitialBar = (CBCGPControlBar*) m_lstControlBars.GetHead ();
}
ASSERT_VALID (pInitialBar);
if (nAvailLength < 0)
{
pInitialBar->StretchBar (nAvailLength, hdwp);
CRect rectBar;
pInitialBar->GetWindowRect (rectBar);
m_pParentDockBar->ScreenToClient (rectBar);
if (IsHorizontal ())
{
rectBar.OffsetRect (-rectBar.TopLeft ().x, -rectBar.TopLeft ().y + m_nRowOffset);
}
else
{
rectBar.OffsetRect (-rectBar.TopLeft ().x + m_nRowOffset, -rectBar.TopLeft ().y);
}
pInitialBar->SetWindowPos (NULL, rectBar.left, rectBar.top,
rectBar.Width (), rectBar.Height (), SWP_NOZORDER | SWP_NOACTIVATE);
return;
}
}
if (pInitialBar != NULL)
{
ResolveIntersection (pInitialBar, false, hdwp);
}
if (pInitialBar == NULL)
{
pInitialBar = (CBCGPControlBar*) m_lstControlBars.GetHead ();
}
ResolveIntersection (pInitialBar, true, hdwp);
CBCGPControlBar* pFirstBar = FindFirstVisibleBar (TRUE);
// how far the first bar is out of row bounds
int nLeftOuterOffset = GetOutOfBoundsOffset (pFirstBar, TRUE);
if (nLeftOuterOffset > 0)
{
ShiftControlBars (pFirstBar, nLeftOuterOffset, TRUE);
}
CBCGPControlBar* pLastBar = FindFirstVisibleBar (FALSE);
int nRightOuterOffset = GetOutOfBoundsOffset (pLastBar, FALSE);
int nStretchSize = 0;
if (nRightOuterOffset > 0 && nAvailLength > 0)
{
ShiftControlBars (pLastBar, -nRightOuterOffset, FALSE);
}
else if (nRightOuterOffset > 0 && nAvailLength <= 0)
{
nStretchSize = nAvailLength;
ShiftControlBars (pLastBar, -(nRightOuterOffset - abs (nAvailLength)), FALSE);
}
else if (nRightOuterOffset < 0)
{
// nothing to do
}
if (nStretchSize < 0)
{
for (POSITION pos = m_lstControlBars.GetTailPosition (); pos != NULL;)
{
CBCGPControlBar* pPrevBar = (CBCGPControlBar*) m_lstControlBars.GetPrev (pos);
ASSERT_VALID (pPrevBar);
if (!pPrevBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
int nRetSize = pPrevBar->StretchBar (nStretchSize, hdwp);
MoveControlBar (pPrevBar, abs (nStretchSize) - abs (nRetSize), false, hdwp);
if (nRetSize == nStretchSize)
{
break;
}
else
{
nStretchSize -= nRetSize;
}
}
}
}
//**********************************************************************************************
CBCGPControlBar* CBCGPDockBarRow::FindFirstVisibleBar (BOOL bForward)
{
ASSERT_VALID (this);
if (m_lstControlBars.IsEmpty ())
{
return NULL;
}
for (POSITION pos = bForward ? m_lstControlBars.GetHeadPosition () :
m_lstControlBars.GetTailPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*)
(bForward ? m_lstControlBars.GetNext (pos) : m_lstControlBars.GetPrev (pos));
ASSERT_VALID (pNextBar);
if (!m_bIgnoreBarVisibility)
{
if (pNextBar->IsVisible ())
{
return pNextBar;
}
}
else
{
return pNextBar;
}
}
return NULL;
}
//**********************************************************************************************
int CBCGPDockBarRow::GetOutOfBoundsOffset (CBCGPControlBar* pBar, BOOL bLeftTopBound)
{
ASSERT_VALID (this);
CRect rectBar;
CRect rectRow;
if (pBar == NULL)
{
pBar = (CBCGPControlBar* )
(bLeftTopBound ? m_lstControlBars.GetHead () : m_lstControlBars.GetTail ());
}
ASSERT_VALID (pBar);
pBar->GetWindowRect (rectBar);
GetWindowRect (rectRow);
int nBoundOffset = 0;
// the offset is greater than zero if the bar is out of bounds
if (IsHorizontal ())
{
nBoundOffset = bLeftTopBound ? rectRow.left - rectBar.left :
rectBar.right - rectRow.right;
}
else
{
nBoundOffset = bLeftTopBound ? rectRow.top - rectBar.top :
rectBar.bottom - rectRow.bottom;
}
return nBoundOffset;
}
//**********************************************************************************************
void CBCGPDockBarRow::RepositionBars (CRect& rectNewParentBarArea, UINT nSide, BOOL bExpand, int nOffset)
{
ASSERT_VALID (this);
if (m_lstControlBars.IsEmpty () ||
GetVisibleCount () == 0)
{
return;
}
CRect rectNewParentWnd = rectNewParentBarArea;
ASSERT_VALID (m_pParentDockBar);
m_pParentDockBar->ClientToScreen (rectNewParentWnd);
CRect rectRowWnd;
GetWindowRect (rectRowWnd);
if (rectRowWnd.IsRectEmpty ())
{
return;
}
int nStretchSize = IsHorizontal () ? rectNewParentWnd.Width () - rectRowWnd.Width () :
rectNewParentWnd.Height () - rectRowWnd.Height ();
HDWP hdwp = NULL; //BeginDeferWindowPos (m_lstControlBars.GetCount ());
// handle exclusive bars first
if (IsExclusiveRow ())
{
CBCGPControlBar* pBar = (CBCGPControlBar*) m_lstControlBars.GetHead ();
ASSERT_VALID (pBar);
ASSERT (!pBar->DoesAllowSiblingBars ());
if (IsHorizontal ())
{
pBar->SetWindowPos (NULL, rectRowWnd.left, rectRowWnd.top,
rectNewParentWnd.Width (),
rectRowWnd.Height (), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
else
{
pBar->SetWindowPos (NULL, rectRowWnd.left, rectRowWnd.top,
rectRowWnd.Width (),
rectNewParentWnd.Height (), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
pBar->RedrawWindow ();
return;
}
int nAvailSpace = GetAvailableLength (TRUE);
bool bResizeBars = nAvailSpace < 0 ||
!bExpand && nAvailSpace >= 0 && nAvailSpace < abs (nStretchSize);
if (bResizeBars)
{
if (!bExpand)
{
// there is some available space on the row
// we need to move control bars first and then stretch
bool bTopLeftSide = (nSide == WMSZ_TOP || nSide == WMSZ_LEFT);
int nActualStretchSize = nStretchSize;
if (nAvailSpace >= 0)
{
int nSign = nStretchSize < 0 ? (-1) : 1;
int nOutOfBoundOffset = GetOutOfBoundsOffset (NULL, bTopLeftSide);
int nOffsetToShift = nAvailSpace - abs (nOutOfBoundOffset);
ShiftControlBars (NULL, nSign * nOffsetToShift, bTopLeftSide);
nActualStretchSize = (abs (nStretchSize) - nAvailSpace) * nSign;
}
for (POSITION pos = m_lstControlBars.GetTailPosition (); pos != NULL;)
{
CBCGPControlBar* pPrevBar = (CBCGPControlBar*) m_lstControlBars.GetPrev (pos);
ASSERT_VALID (pPrevBar);
if (!pPrevBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
int nRetSize = pPrevBar->StretchBar (nActualStretchSize, hdwp);
MoveControlBar (pPrevBar, abs (nActualStretchSize) - abs (nRetSize), bTopLeftSide, hdwp);
if (nRetSize == nActualStretchSize)
{
break;
}
else
{
nActualStretchSize -= nRetSize;
}
}
return;
}
else
{
int nActualStretchSize = nStretchSize;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
int nRetSize = pNextBar->StretchBar (nActualStretchSize, hdwp);
if (nRetSize != 0 && pos != NULL)
{
for (POSITION posMovedBars = pos; posMovedBars != NULL;)
{
CBCGPControlBar* pBarToMove = (CBCGPControlBar*) m_lstControlBars.GetNext (posMovedBars);
ASSERT_VALID (pBarToMove);
if (!pBarToMove->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
MoveControlBar (pBarToMove, nRetSize, true, hdwp);
}
}
nActualStretchSize -= nRetSize;
if (nActualStretchSize <= 0)
{
break;
}
}
}
}
// adlust control bars (first and last) to the row area and try to move
// them as close as it possible to their virtual rectangle
if (IsHorizontal ())
{
rectRowWnd.left = rectNewParentWnd.left;
rectRowWnd.right = rectNewParentWnd.right;
}
else
{
rectRowWnd.top = rectNewParentWnd.top;
rectRowWnd.bottom = rectNewParentWnd.bottom;
}
// check the first and last control bars
CBCGPControlBar* pBarFirst = FindFirstVisibleBar (TRUE);
ASSERT_VALID (pBarFirst);
AdjustBarToRowArea (pBarFirst, rectRowWnd, hdwp);
CBCGPControlBar* pBarLast = FindFirstVisibleBar (FALSE);
ASSERT_VALID (pBarLast);
if (pBarFirst != pBarLast)
{
AdjustBarToRowArea (pBarLast, rectRowWnd, hdwp);
}
if (nSide != (UINT)-1 && bExpand && GetAvailableLength (TRUE) + nStretchSize > 0)
{
CRect rectNextControlBar;
CRect rectNextControlBarVirt;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
pNextBar->GetWindowRect (&rectNextControlBar);
pNextBar->GetVirtualRect (rectNextControlBarVirt);
if (rectNextControlBar != rectNextControlBarVirt)
{
// always try to move to the virtual rect's direction
// if the bar is currently on the left side of its virtual rect
// move it forward, otherwise - backward
bool bMoveBackward = (IsHorizontal () && rectNextControlBar.left > rectNextControlBarVirt.left) ||
(!IsHorizontal () && rectNextControlBar.top > rectNextControlBarVirt.top);
int nOffsetToMove = 0;
if (IsHorizontal () && (nSide == WMSZ_LEFT || nSide == WMSZ_RIGHT))
{
nOffsetToMove = min (abs (nOffset),
abs (rectNextControlBarVirt.left - rectNextControlBar.left));
}
else if (!IsHorizontal () && (nSide == WMSZ_TOP || nSide == WMSZ_BOTTOM))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -