📄 bcgpcontrolbar.cpp
字号:
// BCGPControlBar.cpp : implementation file
//
#include "stdafx.h"
#include "BCGGlobals.h"
#include "BCGPDockBar.h"
#include "BCGPDockBarRow.h"
#include "BCGPMiniFrameWnd.h"
#include "BCGPControlBar.h"
#include "BCGPTabWnd.h"
#include "BCGPTabbedControlBar.h"
#include "BCGPTabbedToolbar.h"
#include "BCGPDockingCBWrapper.h"
#include "BCGPDockManager.h"
#include "BCGPGlobalUtils.h"
#include "BCGPOleCntrFrameWnd.h"
#include "RegPath.h"
#include "BCGPRegistry.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const CString strControlBarProfile = _T ("BCGControlBars");
#define REG_SECTION_FMT _T("%sBCGPControlBar-%d")
#define REG_SECTION_FMT_EX _T("%sBCGPControlBar-%d%x")
IMPLEMENT_DYNCREATE(CBCGPControlBar, CBCGPBaseControlBar)
/////////////////////////////////////////////////////////////////////////////
// CBCGPControlBar
#pragma warning (disable : 4355)
CBCGPControlBar::CBCGPControlBar() : m_bCaptured (false),
m_nID (0),
m_bDisableMove (false),
m_recentDockInfo (this)
{
m_cxLeftBorder = m_cxRightBorder = 6;
m_cxDefaultGap = 2;
m_cyTopBorder = m_cyBottomBorder = 2;
m_pData = NULL;
m_nCount = 0;
m_nMRUWidth = 32767;
m_bDblClick = false;
m_ptClientHotSpot.x = m_ptClientHotSpot.y = 0;
m_rectSavedDockedRect.SetRectEmpty ();
m_bDragMode = FALSE;
m_bWasFloatingBeforeMove = FALSE;
m_bRecentFloatingState = FALSE;
m_pMiniFrameRTC = RUNTIME_CLASS (CBCGPMiniFrameWnd);
m_rectDragImmediate.SetRectEmpty ();
m_hwndMiniFrameToBeClosed = NULL;
m_bFirstInGroup = TRUE;
m_bLastInGroup = TRUE;
m_bActiveInGroup = TRUE;
m_bExclusiveRow = FALSE;
m_bPinState = FALSE;
m_sizeMin.cx = m_sizeMin.cy = 1;
}
#pragma warning (default : 4355)
CBCGPControlBar::~CBCGPControlBar()
{
// free array
if (m_pData != NULL)
{
ASSERT(m_nCount != 0);
free(m_pData);
}
}
BEGIN_MESSAGE_MAP(CBCGPControlBar, CBCGPBaseControlBar)
//{{AFX_MSG_MAP(CBCGPControlBar)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
ON_WM_NCDESTROY()
ON_WM_CONTEXTMENU()
ON_WM_CANCELMODE()
ON_WM_CHAR()
ON_WM_DESTROY()
ON_WM_WINDOWPOSCHANGING()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGPControlBar message handlers
BOOL CBCGPControlBar::Create(LPCTSTR lpszClassName, DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID, DWORD dwBCGStyle,
CCreateContext* pContext)
{
return CBCGPControlBar::CreateEx (0, lpszClassName, dwStyle, rect, pParentWnd, nID, dwBCGStyle, pContext);
}
//***********************************************************************************//
BOOL CBCGPControlBar::CreateEx(DWORD dwStyleEx, LPCTSTR lpszClassName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwBCGStyle,
CCreateContext* pContext)
{
ASSERT_VALID (this);
ASSERT_VALID (pParentWnd);
CString strClassName;
if (lpszClassName == NULL)
{
//-----------------------------
// Register a new window class:
//-----------------------------
HINSTANCE hInst = AfxGetInstanceHandle();
UINT uiClassStyle = CS_DBLCLKS;
HCURSOR hCursor = ::LoadCursor (NULL, IDC_ARROW);
HBRUSH hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
strClassName.Format (_T("BCGControlBar:%x:%x:%x:%x"),
(UINT)hInst, uiClassStyle, (UINT)hCursor, (UINT)hbrBackground);
//---------------------------------
// See if the class already exists:
//---------------------------------
WNDCLASS wndcls;
if (::GetClassInfo (hInst, strClassName, &wndcls))
{
//-----------------------------------------------
// Already registered, assert everything is good:
//-----------------------------------------------
ASSERT (wndcls.style == uiClassStyle);
}
else
{
//-------------------------------------------
// Otherwise we need to register a new class:
//-------------------------------------------
wndcls.style = uiClassStyle;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = hCursor;
wndcls.hbrBackground = hbrBackground;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = strClassName;
if (!AfxRegisterClass (&wndcls))
{
AfxThrowResourceException();
}
}
}
else
{
strClassName = lpszClassName;
}
m_nID = nID;
dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
if (!CBCGPBaseControlBar::CreateEx (dwStyleEx, strClassName, NULL, dwStyle, rect, pParentWnd, nID, dwBCGStyle, pContext))
{
return FALSE;
}
CRect rectInit = rect;
pParentWnd->ClientToScreen (rectInit);
if (m_recentDockInfo.m_recentMiniFrameInfo.m_rectDockedRect.IsRectEmpty ())
{
m_recentDockInfo.m_recentMiniFrameInfo.m_rectDockedRect = rectInit;
}
if (m_recentDockInfo.m_recentSliderInfo.m_rectDockedRect.IsRectEmpty ())
{
m_recentDockInfo.m_recentSliderInfo.m_rectDockedRect = rectInit;
}
if (!rectInit.IsRectEmpty ())
{
m_recentDockInfo.m_rectRecentFloatingRect = rectInit;
}
SetOwner (pParentWnd);
UpdateVirtualRect ();
if (m_dwBCGStyle & CanFloat ())
{
m_dragFrameImpl.Init (this);
}
return TRUE;
}
//***********************************************************************************
void CBCGPControlBar::SetBorders (int cxLeft, int cyTop, int cxRight, int cyBottom)
{
m_cxLeftBorder = cxLeft;
m_cxRightBorder = cxRight;
m_cyTopBorder = cyTop;
m_cyBottomBorder = cyBottom;
}
//**********************************************************************************
void CBCGPControlBar::SetBorders (LPCRECT lpRect)
{
m_cxLeftBorder = lpRect->left;
m_cxRightBorder = lpRect->right;
m_cyTopBorder = lpRect->top;
m_cyBottomBorder = lpRect->bottom;
}
//***********************************************************************************
CRect CBCGPControlBar::GetBorders () const
{
CRect rect (m_cxLeftBorder, m_cyTopBorder, m_cxRightBorder, m_cyBottomBorder);
return rect;
}
//***********************************************************************************
void CBCGPControlBar::OnLButtonDown(UINT nFlags, CPoint point)
{
ASSERT_VALID (this);
if (!m_bCaptured && CanFloat ())
{
CBCGPMiniFrameWnd* pMiniFrame = GetParentMiniFrame ();
if (GetDockMode () == DT_IMMEDIATE || pMiniFrame != NULL)
{
StoreRecentDockInfo ();
if (pMiniFrame == NULL)
{
EnterDragMode (TRUE);
m_bWasFloatingBeforeMove = FALSE;
}
else if (pMiniFrame != NULL)
{
ASSERT_VALID (pMiniFrame);
// it's on the miniframe - reflect message to the miniframe if
// this bar is alone on the miniframe
if (pMiniFrame->GetControlBarCount () == 1)
{
MapWindowPoints (pMiniFrame, &point, 1);
pMiniFrame->SendMessage (WM_LBUTTONDOWN, nFlags, MAKELPARAM (point.x, point.y));
m_bWasFloatingBeforeMove = TRUE;
}
else
{
EnterDragMode (TRUE);
m_bWasFloatingBeforeMove = FALSE;
}
return;
}
}
else if (GetDockMode () == DT_STANDARD)
{
EnterDragMode (TRUE);
}
}
CWnd::OnLButtonDown(nFlags, point);
}
//***********************************************************************************
// EnterDragMode is called from OnLButtonDown and OnContinueMoving - when docked
// in the last case we dont need to save recent floating info and client hot spot
//***********************************************************************************
void CBCGPControlBar::EnterDragMode (BOOL bChangeHotPoint)
{
ASSERT_VALID (this);
CPoint ptCursorPos;
GetCursorPos (&ptCursorPos);
// fixup the current virtual rectangle when mouse btn is down - to be
// prepared to move THIS control bar
UpdateVirtualRect ();
if (bChangeHotPoint)
{
m_ptClientHotSpot = ptCursorPos;
ScreenToClient (&m_ptClientHotSpot);
}
if (!m_bCaptured && IsDocked ())
{
SetCapture ();
m_bCaptured = true;
m_dragFrameImpl.m_ptHot = ptCursorPos;
SetDragMode (TRUE);
GetWindowRect (m_rectDragImmediate);
}
}
//***********************************************************************************
void CBCGPControlBar::StoreRecentDockInfo ()
{
m_recentDockInfo.m_pRecentDockBarRow = m_pDockBarRow;
m_recentDockInfo.m_pRecentDockBar = m_pParentDockBar;
if (m_recentDockInfo.m_pRecentDockBar != NULL)
{
m_recentDockInfo.m_nRecentRowIndex =
m_recentDockInfo.m_pRecentDockBar->FindRowIndex (m_pDockBarRow);
}
CalcRecentDockedRect ();
}
//***********************************************************************************
void CBCGPControlBar::OnLButtonUp(UINT nFlags, CPoint point)
{
ASSERT_VALID (this);
CBCGPMiniFrameWnd* pMiniFrame = GetParentMiniFrame ();
if (m_bCaptured)
{
ReleaseCapture ();
m_bCaptured = false;
if (nFlags != 0xFFFF)
{
if (m_hwndMiniFrameToBeClosed != NULL && ::IsWindow (m_hwndMiniFrameToBeClosed))
{
::DestroyWindow (m_hwndMiniFrameToBeClosed);
}
m_hwndMiniFrameToBeClosed = NULL;
}
SetDragMode (FALSE);
if (GetDockMode () == DT_STANDARD &&
(m_dragFrameImpl.m_bDragStarted || m_dragFrameImpl.m_nInsertedTabID >= 0))
{
CRect rectFinal = m_dragFrameImpl.m_rectDrag;
if (m_dragFrameImpl.m_bDragStarted &&
GetDockMode () == DT_STANDARD)
{
m_dragFrameImpl.EndDrawDragFrame ();
}
BOOL bWasDocked = FALSE;
StoreRecentDockInfo ();
CBCGPControlBar* pTargetBar = DockControlBarStandard (bWasDocked);
if (!bWasDocked)
{
if (!rectFinal.IsRectEmpty () && pTargetBar != this)
{
FloatControlBar (rectFinal, DM_STANDARD);
}
}
return;
}
}
else if (pMiniFrame != NULL && !m_bDblClick &&
pMiniFrame->IsWindowVisible ())
{
// it's attached to the miniframe - reflect message to the miniframe
ASSERT_VALID (pMiniFrame);
MapWindowPoints (pMiniFrame, &point, 1);
pMiniFrame->SendMessage (WM_LBUTTONUP, nFlags, MAKELPARAM (point.x, point.y));
return;
}
m_bDblClick = false;
if (m_pDockBarRow != NULL)
{
m_pDockBarRow->FixupVirtualRects (false);
}
CWnd::OnLButtonUp(nFlags, point);
}
//***********************************************************************************
void CBCGPControlBar::OnMouseMove(UINT nFlags, CPoint point)
{
ASSERT_VALID (this);
// the control bar is moved when it resides on the dock bar (docked)
if (m_bCaptured)
{
if (GetDockMode () == DT_IMMEDIATE)
{
CPoint ptMouse;
GetCursorPos (&ptMouse);
CRect rectBar;
GetWindowRect (rectBar);
if (m_pDockBarRow != NULL)
{
CRect rectRow;
m_pDockBarRow->GetWindowRect (rectRow);
}
CPoint ptOffset = ptMouse - m_dragFrameImpl.m_ptHot;
m_rectDragImmediate.OffsetRect (ptOffset);
UpdateVirtualRect (ptOffset);
if (m_pParentDockBar != NULL)
{
m_pParentDockBar->MoveControlBar (this, nFlags, ptOffset);
}
m_dragFrameImpl.m_ptHot = ptMouse;
}
else if (GetDockMode () == DT_STANDARD)
{
m_dragFrameImpl.MoveDragFrame ();
}
}
else
{
// it should be moved (if captured) along with the mini fraeme
CWnd::OnMouseMove(nFlags, point);
}
}
//***********************************************************************************
void CBCGPControlBar::RecalcLayout ()
{
ASSERT_VALID (this);
if (m_pDockBarRow != NULL)
{
UpdateVirtualRect ();
}
else
{
CBCGPMiniFrameWnd* pMiniFrame = GetParentMiniFrame ();
CWnd* pParent = GetParent ();
if (pMiniFrame != NULL && !pParent->IsKindOf (RUNTIME_CLASS (CBCGPTabWnd)))
{
pMiniFrame->OnBarRecalcLayout ();
}
}
}
//***********************************************************************************
void CBCGPControlBar::DoPaint (CDC* pDC)
{
CBCGPBaseControlBar::DoPaint (pDC);
}
//***********************************************************************************
BOOL CBCGPControlBar::DockByMouse (CBCGPBaseControlBar* pDockBar)
{
ASSERT_VALID (this);
if (!OnBeforeDock (&pDockBar, NULL, DM_MOUSE))
{
return FALSE;
}
if (Dock (pDockBar, NULL, DM_MOUSE))
{
OnAfterDock (pDockBar, NULL, DM_MOUSE);
return TRUE;
}
return FALSE;
}
//***********************************************************************************
BOOL CBCGPControlBar::DockControlBar (CBCGPBaseControlBar* pDockBar, LPCRECT lpRect,
BCGP_DOCK_METHOD dockMethod)
{
ASSERT_VALID (this);
if (!OnBeforeDock (&pDockBar, lpRect, dockMethod))
{
return FALSE;
}
if (Dock (pDockBar, lpRect, dockMethod))
{
OnAfterDock (pDockBar, lpRect, dockMethod);
return TRUE;
}
return FALSE;
}
//***********************************************************************************
BOOL CBCGPControlBar::Dock (CBCGPBaseControlBar* pDockBar, LPCRECT lpRect,
BCGP_DOCK_METHOD dockMethod)
{
ASSERT_VALID (this);
ASSERT_VALID (pDockBar);
if (dockMethod == DM_DBL_CLICK)
{
pDockBar = m_recentDockInfo.m_pRecentDockBar;
if (pDockBar == NULL)
{
CBCGPDockManager* pDockManager =
globalUtils.GetDockManager (GetDockSite ());
ASSERT_VALID (pDockManager);
pDockManager->DockControlBar (this);
return TRUE;
}
}
ASSERT_KINDOF (CBCGPDockBar, pDockBar);
// check whether the control bar can be docked at the given DockBar
if (!CanBeDocked (pDockBar) || !pDockBar->CanAcceptBar (this))
{
return FALSE;
}
// save the window rectandle of the control bar, because it will be adjusted in the
// moment when the parent is changed
CRect rect;
rect.SetRectEmpty ();
GetWindowRect (&rect);
BOOL bWasCaptured = TRUE;
CBCGPMiniFrameWnd* pMiniFrame = GetParentMiniFrame ();
if (pMiniFrame != NULL)
{
bWasCaptured = pMiniFrame->IsCaptured ();
}
PrepareToDock ((CBCGPDockBar*)pDockBar, dockMethod);
if (dockMethod == DM_MOUSE)
{
m_pParentDockBar->DockControlBar (this, dockMethod, &rect);
if (bWasCaptured)
{
OnContinueMoving ();
}
}
else if (dockMethod == DM_RECT || dockMethod == DM_DBL_CLICK)
{
m_pParentDockBar->DockControlBar (this, dockMethod, lpRect);
}
return TRUE;
}
//***********************************************************************************
void CBCGPControlBar::PrepareToDock (CBCGPDockBar* pDockBar, BCGP_DOCK_METHOD dockMethod)
{
if (pDockBar != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -