📄 bcgpcontrolbar.cpp
字号:
{
m_pParentDockBar = DYNAMIC_DOWNCAST (CBCGPDockBar, pDockBar);
ASSERT_VALID (m_pParentDockBar);
// remove the control bar from its miniframe
RemoveFromMiniframe (pDockBar, dockMethod);
// align correctly and turn on all borders
DWORD dwStyle = GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
dwStyle &= ~CBRS_FLOATING;
SetBarStyle (dwStyle);
SetBarAlignment (pDockBar->GetCurrentAlignment ());
}
}
//***********************************************************************************
void CBCGPControlBar::RemoveFromMiniframe (CWnd* pNewParent, BCGP_DOCK_METHOD dockMethod)
{
ASSERT_VALID (this);
CBCGPMiniFrameWnd* pMiniFrame = GetParentMiniFrame ();
CWnd* pOldParent = GetParent ();
// reassign the parentship to the new parent
OnBeforeChangeParent (pNewParent);
// miniframe will be NULL if the bar has never been floating
if (pMiniFrame != NULL)
{
// remove the control bar from its miniframe
// DO NOT destroy miniframe meanwhile
// delay destroying of miniframes only in case if it's the first miniframe after
// the control bar has been captured
BOOL bDelayDestroy = (dockMethod == DM_MOUSE && m_hwndMiniFrameToBeClosed == NULL);
pMiniFrame->RemoveControlBar (this, FALSE, bDelayDestroy);
if (dockMethod == DM_MOUSE && m_hwndMiniFrameToBeClosed == NULL)
{
m_hwndMiniFrameToBeClosed = pMiniFrame->GetSafeHwnd ();
}
pMiniFrame->SendMessage (WM_LBUTTONUP, 0, 0);
}
SetParent (pNewParent);
OnAfterChangeParent (pOldParent);
}
//***********************************************************************************
BOOL CBCGPControlBar::OnBeforeDock (CBCGPBaseControlBar** /*ppDockBar*/, LPCRECT /*lpRect*/, BCGP_DOCK_METHOD /*dockMethod*/)
{
ASSERT_VALID (this);
CBCGPMiniFrameWnd* pParentMiniFrame = GetParentMiniFrame ();
if (pParentMiniFrame != NULL)
{
m_bPinState = pParentMiniFrame->GetPinState ();
}
return TRUE;
}
//***********************************************************************************
BOOL CBCGPControlBar::OnBeforeFloat (CRect& /*rectFloat*/, BCGP_DOCK_METHOD /*dockMethod*/)
{
ASSERT_VALID (this);
return TRUE;
}
//***********************************************************************************
void CBCGPControlBar::OnAfterFloat ()
{
ASSERT_VALID (this);
SetBarAlignment (CBRS_ALIGN_TOP);
CBCGPMiniFrameWnd* pParentMiniFrame = GetParentMiniFrame ();
if (pParentMiniFrame != NULL)
{
pParentMiniFrame->Pin (m_bPinState);
}
}
//***********************************************************************************
void CBCGPControlBar::OnContinueMoving ()
{
ASSERT_VALID (this);
// continue moving
EnterDragMode (FALSE);
}
//***********************************************************************************
BOOL CBCGPControlBar::FloatControlBar (CRect rectFloat, BCGP_DOCK_METHOD dockMethod,
bool bShow)
{
ASSERT_VALID (this);
if (!IsDocked () && !IsTabbed ())
{
return TRUE;
}
if (!CanFloat ())
{
return TRUE;
}
CRect rectBeforeFloat;
GetWindowRect (rectBeforeFloat);
CWnd* pDockSite = GetDockSite ();
ASSERT_VALID (pDockSite);
pDockSite->ScreenToClient (rectBeforeFloat);
CPoint ptMouseScreen; //mouse coords
GetCursorPos (&ptMouseScreen);
CPoint ptScreen = m_ptClientHotSpot;
ClientToScreen (&ptScreen);
if (!OnBeforeFloat (rectFloat, dockMethod))
{
return TRUE;
}
CRect rectDelta (16, 16, 16, 16);
globalUtils.AdjustRectToWorkArea (rectFloat, &rectDelta);
// create miniframe if it does not exist and move it if it does exist
CBCGPMiniFrameWnd* pParentMiniFrame = CreateDefaultMiniframe (rectFloat);
if (pParentMiniFrame == NULL)
{
return FALSE;
}
// this rectangle does not take into account miniframe caption height and borders
pParentMiniFrame->m_rectRecentFloatingRect =
m_recentDockInfo.m_rectRecentFloatingRect;
OnBeforeChangeParent (pParentMiniFrame);
CPoint ptMouseClient = ptMouseScreen;
ScreenToClient (&ptMouseClient);
if (dockMethod == DM_MOUSE)
{
SendMessage (WM_LBUTTONUP, 0xFFFF, MAKELPARAM (ptMouseClient.x, ptMouseClient.y));
if (IsTabbed ())
{
CBCGPMiniFrameWnd* pWnd = GetParentMiniFrame ();
if (pWnd != NULL)
{
pWnd->SendMessage (WM_LBUTTONUP, 0, MAKELPARAM (ptMouseClient.x, ptMouseClient.y));
}
}
}
CWnd* pOldParent = GetParent ();
SetParent (pParentMiniFrame);
if (m_pParentDockBar != NULL)
{
OnAfterChangeParent (m_pParentDockBar);
m_pParentDockBar = NULL;
}
else
{
OnAfterChangeParent (pOldParent);
}
pParentMiniFrame->AddControlBar (this);
//move control bar to the top left corner of the miniframe
pParentMiniFrame->CheckGripperVisibility ();
SetWindowPos (&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
if (dockMethod == DM_MOUSE && GetDockMode () == DT_IMMEDIATE)
{
pParentMiniFrame->EnterDragMode ();
// block the first MouseMove to prevent immediate docking
pParentMiniFrame->m_bBlockMove = true;
}
OnAfterFloat ();
DWORD dwStyle = GetBarStyle ();
dwStyle |= CBRS_FLOATING;
SetBarStyle (dwStyle);
RecalcLayout ();
if (bShow)
{
GetParentMiniFrame ()->AdjustLayout ();
}
// move the default miniframe so the client hot spot will be on place
// move the default miniframe so the client hot spot will be on place
if (dockMethod == DM_MOUSE)
{
CRect rectFinalMiniFrame;
pParentMiniFrame->GetWindowRect (rectFinalMiniFrame);
ptScreen = m_ptClientHotSpot;
pParentMiniFrame->ClientToScreen (&ptScreen);
if (ptScreen.x > rectFinalMiniFrame.left + rectFinalMiniFrame.Width () ||
ptScreen.x < rectFinalMiniFrame.left)
{
ptScreen.x = rectFinalMiniFrame.left + rectFinalMiniFrame.Width () / 2;
}
if (ptScreen.y > rectFinalMiniFrame.top + rectFinalMiniFrame.Height () ||
ptScreen.y < rectFinalMiniFrame.top)
{
ptScreen.y = rectFinalMiniFrame.top + pParentMiniFrame->GetCaptionHeight () / 2;
}
CPoint ptOffset = ptMouseScreen - ptScreen;
rectFinalMiniFrame.OffsetRect (ptOffset);
pParentMiniFrame->MoveWindow (rectFinalMiniFrame);
pParentMiniFrame->SetHotPoint (ptMouseScreen);
}
if (bShow)
{
pParentMiniFrame->ShowWindow (SW_SHOW);
GetDockSite ()->RedrawWindow (&rectBeforeFloat, NULL, RDW_FRAME | RDW_INVALIDATE |
RDW_UPDATENOW | RDW_ALLCHILDREN |
RDW_NOINTERNALPAINT | RDW_NOERASE);
if (GetDockSite ()->IsKindOf (RUNTIME_CLASS (CBCGPOleCntrFrameWnd)))
{
((CBCGPOleCntrFrameWnd*) GetDockSite ())->AdjustDockingLayout ();
}
}
return TRUE;
}
//***********************************************************************************
void CBCGPControlBar::OnBeforeChangeParent (CWnd* pWndNewParent, BOOL bDelay)
{
ASSERT_VALID (this);
if (m_pParentDockBar != NULL)
{
m_pParentDockBar->RemoveControlBar (this, DM_UNKNOWN);
}
CBCGPBaseControlBar::OnBeforeChangeParent (pWndNewParent, bDelay);
}
//***********************************************************************************
void CBCGPControlBar::OnAfterChangeParent (CWnd* pWndOldParent)
{
ASSERT_VALID (this);
UpdateVirtualRect ();
if (!GetParent ()->IsKindOf (RUNTIME_CLASS (CBCGPDockBar)))
{
m_pParentDockBar = NULL;
m_pDockBarRow = NULL;
}
CBCGPBaseControlBar::OnAfterChangeParent (pWndOldParent);
}
//***********************************************************************************
BOOL CBCGPControlBar::MoveByAlignment (DWORD dwAlignment, int nOffset)
{
ASSERT_VALID (this);
CRect rect;
GetWindowRect (rect);
CWnd* pParentWnd = GetParent ();
ASSERT_VALID (pParentWnd);
pParentWnd->ScreenToClient (&rect);
switch (dwAlignment & CBRS_ALIGN_ANY)
{
case CBRS_ALIGN_LEFT:
case CBRS_ALIGN_RIGHT:
rect.OffsetRect (nOffset, 0);
UpdateVirtualRect (CPoint (nOffset, 0));
break;
case CBRS_ALIGN_TOP:
case CBRS_ALIGN_BOTTOM:
rect.OffsetRect (0, nOffset);
UpdateVirtualRect (CPoint (0, nOffset));
break;
}
return (BOOL) SetWindowPos (&wndTop, rect.left, rect.top, rect.Width (), rect.Height (),
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
}
//***********************************************************************************
CSize CBCGPControlBar::MoveControlBar (CRect rectNew, BOOL bForceMove, HDWP& hdwp)
{
ASSERT_VALID (this);
CSize sizeMin;
CSize sizeNew = rectNew.Size ();
GetMinSize (sizeMin);
CRect rectCurrent;
GetWindowRect (rectCurrent);
CSize sizeActual = rectNew.Size () - rectCurrent.Size ();
if (!bForceMove && abs (sizeNew.cx) < sizeMin.cx)
{
if (rectCurrent.left == rectNew.left ||
rectCurrent.left != rectNew.left &&
rectCurrent.right != rectNew.right)
{
rectNew.right = rectCurrent.left + sizeMin.cx;
}
else if (rectCurrent.right == rectNew.right)
{
rectNew.left = rectCurrent.right - sizeMin.cx;
}
sizeActual.cx = rectCurrent.Width () - rectNew.Width ();
}
if (!bForceMove && abs (sizeNew.cy) < sizeMin.cy)
{
if (rectCurrent.top == rectNew.top ||
rectCurrent.top != rectNew.top &&
rectCurrent.bottom != rectNew.bottom)
{
rectNew.bottom = rectCurrent.top + sizeMin.cy;
}
else if (rectCurrent.bottom == rectNew.bottom)
{
rectNew.top = rectCurrent.bottom - sizeMin.cy;
}
sizeActual.cy = rectCurrent.Height () - rectNew.Height ();
}
ASSERT_VALID (GetParent ());
GetParent ()->ScreenToClient (rectNew);
MoveWindow (rectNew);
return sizeActual;
}
//***********************************************************************************
int CBCGPControlBar::StretchBar (int nStretchSize, HDWP& hdwp)
{
ASSERT_VALID (this);
// the bar is stretched - calculate how far it can be expanded and do not
// exceed its original size
int nAvailExpandSize = GetAvailableExpandSize ();
int nAvailStretchSize = GetAvailableStretchSize ();
int nActualStretchSize = 0;
if (nStretchSize > 0)
{
if (nAvailExpandSize == 0)
{
return 0;
}
// the bar is expanded
nActualStretchSize = nAvailExpandSize > nStretchSize ? nStretchSize : nAvailExpandSize;
}
else
{
nActualStretchSize = nAvailStretchSize < abs (nStretchSize) ? -nAvailStretchSize : nStretchSize;
}
CRect rect;
GetWindowRect (rect);
if (IsHorizontal ())
{
rect.right += nActualStretchSize;
}
else
{
rect.bottom += nActualStretchSize;
}
OnBeforeStretch (nActualStretchSize);
if (abs (nActualStretchSize) > 0)
{
ASSERT_VALID (GetParent ());
GetParent ()->ScreenToClient (rect);
MoveWindow (rect);
OnAfterStretch (nActualStretchSize);
}
return nActualStretchSize;
}
//***********************************************************************************
int CBCGPControlBar::GetAvailableExpandSize () const
{
ASSERT_VALID (this);
CRect rect;
GetWindowRect (rect);
// can't expand beyond virtual rect
if ((IsHorizontal () && rect.Width () >= m_rectVirtual.Width () ||
!IsHorizontal () && rect.Height () >= m_rectVirtual.Height ()))
{
return 0;
}
return IsHorizontal () ? m_rectVirtual.Width () - rect.Width () :
m_rectVirtual.Height () - rect.Height ();
}
//***********************************************************************************
int CBCGPControlBar::GetAvailableStretchSize () const
{
ASSERT_VALID (this);
CRect rect;
GetWindowRect (rect);
CSize sizeMin;
GetMinSize (sizeMin);
return IsHorizontal () ? rect.Width () - sizeMin.cx:
rect.Height () - sizeMin.cy;
}
//***********************************************************************************
CSize CBCGPControlBar::CalcAvailableSize (CRect rectRequired)
{
ASSERT_VALID (this);
CSize sizeMin;
GetMinSize (sizeMin);
CSize sizeAvailable (0, 0);
if (rectRequired.Width () < sizeMin.cx)
{
rectRequired.right = rectRequired.left + sizeMin.cx;
}
if (rectRequired.Height () < sizeMin.cy)
{
rectRequired.bottom = rectRequired.top + sizeMin.cy;
}
CRect rectCurrent;
GetWindowRect (rectCurrent);
// available space is negative when stretching
sizeAvailable.cx = rectRequired.Width () - rectCurrent.Width ();
sizeAvailable.cy = rectRequired.Height () - rectCurrent.Height ();
return sizeAvailable;
}
//***********************************************************************************
bool CBCGPControlBar::IsLeftOf (CRect rect, bool bWindowRect) const
{
ASSERT_VALID (this);
if (m_pParentDockBar == NULL)
{
return true;
}
CRect rectBar;
GetWindowRect (&rectBar);
if (!bWindowRect)
{
m_pParentDockBar->ScreenToClient (&rectBar);
}
if (m_pParentDockBar->IsHorizontal ())
{
return (rect.left < rectBar.left);
}
else
{
return (rect.top < rectBar.top);
}
}
//***********************************************************************************
bool CBCGPControlBar::IsLastBarOnLastRow () const
{
ASSERT_VALID (this);
if (m_pParentDockBar->IsLastRow (m_pDockBarRow))
{
return (m_pDockBarRow->GetBarCount () == 1);
}
return false;
}
//***********************************************************************************
BCGP_CS_STATUS CBCGPControlBar::IsChangeState (int nOffset,
CBCGPBaseControlBar** ppTargetBar) const
{
ASSERT_VALID (this);
ASSERT (ppTargetBar != NULL);
CPoint ptMousePos;
CRect rectBarWnd;
CRect rectDockBarWnd;
CRect rectIntersect;
CRect rectVirtual;
CPoint ptDelta;
GetCursorPos (&ptMousePos);
GetWindowRect (&rectBarWnd);
GetVirtualRect (rectVirtual);
// check whether the mouse is around a dock bar
CBCGPBaseControlBar* pBaseBar = ControlBarFromPoint (ptMousePos, nOffset, FALSE,
RUNTIME_CLASS (CBCGPDockBar));
*ppTargetBar = DYNAMIC_DOWNCAST (CBCGPDockBar, pBaseBar);
if (m_pParentDockBar != NULL)
{
// the mouse is around the dock bar, check the virtual rect
m_pParentDockBar->GetWindowRect (&rectDockBarWnd);
if (!rectIntersect.IntersectRect (rectDockBarWnd, rectVirtual))
{
return CS_DOCK_IMMEDIATELY;
}
// there is some intersection of the virtual rectangle an the dock bar.
// special processing when horizontal bar is about to float in horizontal direction
bool bTreatMouse = false;
if (m_pParentDockBar->IsHorizontal ())
{
if (rectVirtual.left < rectDockBarWnd.left &&
rectDockBarWnd.left - rectVirtual.left > nOffset * 2 ||
rectVirtual.right > rectDockBarWnd.right &&
rectVirtual.right - rectDockBarWnd.right > nOffset * 2)
{
bTreatMouse = true;
}
}
else
{
if (rectVirtual.top < rectDockBarWnd.top &&
rectDockBarWnd.top - rectVirtual.top > nOffset * 2 ||
rectVirtual.bottom > rectDockBarWnd.bottom &&
rectVirtual.bottom - rectDockBarWnd.bottom > nOffset * 2)
{
bTreatMouse = true;
}
}
if (bTreatMouse && !rectDockBarWnd.PtInRect (ptMousePos))
{
return CS_DOCK_IMMEDIATELY;
}
}
else
{
if (*ppTargetBar == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -