📄 bcgpbasetabwnd.cpp
字号:
// BCGPBaseTabWnd.cpp : implementation file
//
#include "stdafx.h"
#include "bcgcbpro.h"
#include "BCGPBaseTabWnd.h"
#include "BCGPDockingControlBar.h"
#include "BCGPDockingCBWrapper.h"
#include "BCGPBaseTabbedBar.h"
#include "BCGPMiniFrameWnd.h"
#include "BCGPDockManager.h"
#include "BCGPGlobalUtils.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBCGPTabDropTarget message handlers
//***************************************************************************************
BOOL CBCGPTabDropTarget::Register (CBCGPBaseTabWnd *pOwner)
{
m_pOwner = pOwner;
return COleDropTarget::Register (pOwner);
}
//***************************************************************************************
DROPEFFECT CBCGPTabDropTarget::OnDragEnter(CWnd* /*pWnd*/, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
ASSERT (m_pOwner != NULL);
if (!CBCGPToolBar::IsCustomizeMode () ||
!pDataObject->IsDataAvailable (CBCGPToolbarButton::m_cFormat))
{
return DROPEFFECT_NONE;
}
return m_pOwner->OnDragEnter(pDataObject, dwKeyState, point);
}
//***************************************************************************************
void CBCGPTabDropTarget::OnDragLeave(CWnd* /*pWnd*/)
{
ASSERT (m_pOwner != NULL);
m_pOwner->OnDragLeave ();
}
//***************************************************************************************
DROPEFFECT CBCGPTabDropTarget::OnDragOver(CWnd* /*pWnd*/, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
ASSERT (m_pOwner != NULL);
if (!CBCGPToolBar::IsCustomizeMode () ||
!pDataObject->IsDataAvailable (CBCGPToolbarButton::m_cFormat))
{
return DROPEFFECT_NONE;
}
return m_pOwner->OnDragOver(pDataObject, dwKeyState, point);
}
//***************************************************************************************
DROPEFFECT CBCGPTabDropTarget::OnDropEx(CWnd* /*pWnd*/,
COleDataObject* pDataObject,
DROPEFFECT dropEffect,
DROPEFFECT /*dropList*/, CPoint point)
{
ASSERT (m_pOwner != NULL);
if (!CBCGPToolBar::IsCustomizeMode () ||
!pDataObject->IsDataAvailable (CBCGPToolbarButton::m_cFormat))
{
return DROPEFFECT_NONE;
}
return m_pOwner->OnDrop(pDataObject, dropEffect, point) ?
dropEffect : DROPEFFECT_NONE;
}
/////////////////////////////////////////////////////////////////////////////
// CBCGPBaseTabWnd
int CBCGPBaseTabWnd::TAB_TEXT_MARGIN = 4;
int CBCGPBaseTabWnd::TAB_IMAGE_MARGIN = 4;
#define DEFAULT_TAB_BORDER_SIZE 2
UINT BCGM_ON_RENAME_TAB = ::RegisterWindowMessage (_T("BCGM_ON_RENAME_TAB"));
UINT BCGM_CHANGE_ACTIVE_TAB = ::RegisterWindowMessage (_T("BCGM_ONCHANGE_ACTIVE_TAB"));
UINT BCGM_ON_MOVE_TAB = ::RegisterWindowMessage (_T("BCGM_ON_MOVE_TAB"));
UINT BCGM_CHANGING_ACTIVE_TAB = ::RegisterWindowMessage (_T("BCGM_ON_CHANGING_ACTIVE_TAB"));
IMPLEMENT_DYNAMIC(CBCGPBaseTabWnd, CWnd)
CBCGPBaseTabWnd::CBCGPBaseTabWnd()
{
m_bAutoDestoyWindow = FALSE;
m_iActiveTab = -1;
m_iTabBeforeDrag = -1;
m_iTabsNum = 0;
m_sizeImage = CSize (0, 0);
m_hImageList = NULL;
m_iCurTab = -1;
m_nNextTabID = 1;
m_bHideInactiveWnd = TRUE;
m_location = LOCATION_BOTTOM;
m_bReadyToDetach = FALSE;
m_ptHot = CPoint (0, 0);
m_nOffsetFromTabLeft = 0;
m_iHighlighted = -1;
m_iPressed = -1;
m_bActivateOnBtnUp = FALSE;
m_bEnableTabSwap = TRUE;
m_nRestoredActiveTabID = 0;
m_pDockingBarWrapperRTC = NULL;
m_bEnableWrapping = FALSE;
m_clrActiveTabBk = (COLORREF) -1;
m_clrActiveTabFg = (COLORREF) -1;
m_nTabBorderSize = DEFAULT_TAB_BORDER_SIZE;
m_nTabsHeight = 0;
// in-place editing
m_pInPlaceEdit = NULL;
m_iEditedTab = -1;
m_bIsInPlaceEdit = FALSE;
m_bHideSingleTab = FALSE;
m_bLabelNoPrefix = FALSE;
m_bActivateLastVisibleTab = FALSE;
m_bHighLightTabs = FALSE;
m_bIsAutoColor = FALSE;
m_bIsDefaultAutoColor = TRUE;
m_bIsDlgControl = FALSE;
m_iLastActiveTab = -1;
m_bActivateLastActiveTab = FALSE;
}
//***************************************************************************************
CBCGPBaseTabWnd::~CBCGPBaseTabWnd()
{
}
BEGIN_MESSAGE_MAP(CBCGPBaseTabWnd, CWnd)
//{{AFX_MSG_MAP(CBCGPBaseTabWnd)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_MOUSEMOVE()
ON_WM_CANCELMODE()
ON_WM_DESTROY()
ON_WM_CREATE()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGPBaseTabWnd message handlers
//***************************************************************************************
void CBCGPBaseTabWnd::CleanUp ()
{
for (int i = 0; i < m_iTabsNum; i ++)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTab);
// we need to delete tab info only in the case the contained window is not
// derived from CBCGPControlBar, because CBCGPControlBar detects that it's
// tabbed while processing OnDestroy and removes itself from the parent tabbed
// window.
BOOL bDeleteTabInfo = !pTab->m_pWnd->IsKindOf (RUNTIME_CLASS (CBCGPControlBar));
if (m_bAutoDestoyWindow)
{
pTab->m_pWnd->DestroyWindow ();
}
if (bDeleteTabInfo || !m_bAutoDestoyWindow)
{
delete pTab;
}
}
m_arTabs.RemoveAll ();
m_iTabsNum = 0;
m_iActiveTab = -1;
}
//***************************************************************************************
void CBCGPBaseTabWnd::AddTab (CWnd* pNewWnd, LPCTSTR lpszName, UINT uiImageId, BOOL bDetachable)
{
if (pNewWnd->GetSafeHwnd () != NULL && pNewWnd->GetDlgCtrlID () == -1)
{
ASSERT (FALSE);
TRACE0 ("Unable to add a new tab with control bar ID -1. \n");
return;
}
CWnd* pWndToAdd = CreateWrapper (pNewWnd, lpszName, bDetachable);
ASSERT_VALID (pWndToAdd);
InsertTab (pWndToAdd, lpszName, -1, uiImageId, bDetachable);
}
//***************************************************************************************
void CBCGPBaseTabWnd::AddTab (CWnd* pTabWnd, UINT uiResTabLabel, UINT uiImageId, BOOL bDetachable)
{
ASSERT_VALID (this);
ASSERT_VALID (pTabWnd);
if (pTabWnd->GetDlgCtrlID () == -1)
{
ASSERT (FALSE);
TRACE0 ("Unable to add a new tab with control bar ID -1. \n");
return;
}
CString strLabel;
strLabel.LoadString (uiResTabLabel);
CWnd* pWndToAdd = CreateWrapper (pTabWnd, strLabel, bDetachable);
ASSERT_VALID (pWndToAdd);
AddTab (pWndToAdd, strLabel, uiImageId, bDetachable);
}
//***************************************************************************************
void CBCGPBaseTabWnd::InsertTab(CWnd* pNewWnd, LPCTSTR lpszTabLabel, int nInsertAt, UINT uiImageId, BOOL bDetachable)
{
ASSERT_VALID (this);
ASSERT_VALID (pNewWnd);
ASSERT (lpszTabLabel != NULL);
CWnd* pWndToAdd = CreateWrapper (pNewWnd, lpszTabLabel, bDetachable);
ASSERT_VALID (pWndToAdd);
if (!IsWindowVisible ())
{
ShowWindow (SW_SHOW);
}
if (nInsertAt < 0 || nInsertAt > m_iTabsNum)
{
nInsertAt = m_iTabsNum;
}
CWnd* pActiveWnd = GetActiveWnd();
// can't detach non-docking control bar derived objects
if (!pWndToAdd->IsKindOf (RUNTIME_CLASS (CBCGPDockingControlBar)))
{
bDetachable = FALSE;
}
m_arTabs.InsertAt (nInsertAt, new CBCGPTabInfo (
lpszTabLabel, uiImageId, pWndToAdd, m_nNextTabID, bDetachable));
m_iTabsNum++;
if (m_ToolTip.GetSafeHwnd () != NULL)
{
CRect rectEmpty (0, 0, 0, 0);
m_ToolTip.AddTool (this, lpszTabLabel, &rectEmpty, m_nNextTabID);
}
m_nNextTabID ++;
RecalcLayout ();
if (m_iTabsNum == 1)
{
//----------------------------------------
// First tab automatically becames active:
//----------------------------------------
SetActiveTab (0);
}
else
{
m_iLastActiveTab = m_iActiveTab;
if (m_iActiveTab == nInsertAt)
{
m_iLastActiveTab++;
if (m_bHideInactiveWnd && pActiveWnd != NULL)
{
pActiveWnd->ShowWindow(SW_HIDE);
}
pWndToAdd->ShowWindow (SW_SHOWNORMAL);
}
else if (m_bHideInactiveWnd)
{
if (pWndToAdd->GetSafeHwnd () != NULL)
{
pWndToAdd->ShowWindow(SW_HIDE);
}
}
}
if (!m_bHideInactiveWnd && pActiveWnd != NULL &&
pActiveWnd->GetSafeHwnd () != NULL)
{
pActiveWnd->BringWindowToTop ();
}
}
//***************************************************************************************
void CBCGPBaseTabWnd::InsertTab(CWnd* pNewWnd, UINT uiResTabLabel, int nInsertAt,
UINT uiImageId, BOOL bDetachable)
{
ASSERT_VALID (this);
ASSERT_VALID (pNewWnd);
if (pNewWnd->GetDlgCtrlID () == -1)
{
ASSERT (FALSE);
TRACE0 ("Unable to add a new tab with control bar ID -1. \n");
return;
}
CString strLabel;
strLabel.LoadString (uiResTabLabel);
CWnd* pWndToAdd = CreateWrapper (pNewWnd, strLabel, bDetachable);
ASSERT_VALID (pWndToAdd);
InsertTab (pWndToAdd, strLabel, nInsertAt, uiImageId, bDetachable);
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::RemoveTab (int iTab, BOOL bRecalcLayout)
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
TRACE(_T("RemoveTab: illegal tab number %d\n"), iTab);
return FALSE;
}
if (m_iTabsNum == 1)
{
RemoveAllTabs ();
return TRUE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
if (m_ToolTip.GetSafeHwnd () != NULL)
{
m_ToolTip.DelTool (this, pTab->m_iTabID);
}
//----------------------------
// Detach tab from collection:
//----------------------------
m_arTabs.RemoveAt (iTab);
m_iTabsNum --;
//-----------------------------------
// Destroy tab window and delete tab:
//-----------------------------------
if (m_bAutoDestoyWindow)
{
ASSERT_VALID (pTab->m_pWnd);
pTab->m_pWnd->DestroyWindow ();
}
delete pTab;
int iActiveTab = m_iActiveTab;
if (m_iActiveTab >= iTab)
{
if (m_bActivateLastVisibleTab)
{
GetLastVisibleTab (iActiveTab);
}
else
{
// Find the next best tab to be activated
for (int i = m_iTabsNum - 1; i >= 0; --i)
{
CBCGPTabInfo* pNextActiveTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pNextActiveTab);
if (i < iTab && iActiveTab >= 0 && iActiveTab < m_iTabsNum)
{
break;
}
if (pNextActiveTab->m_bVisible)
{
iActiveTab = i;
}
}
}
m_iActiveTab = -1;
}
if (bRecalcLayout)
{
RecalcLayout ();
if (iActiveTab != -1)
{
if (m_bActivateLastActiveTab && (m_iLastActiveTab != -1))
{
int iLastActiveTab = m_iLastActiveTab;
if (iTab < m_iLastActiveTab)
{
iLastActiveTab = m_iLastActiveTab -1;
}
SetActiveTab (iLastActiveTab);
}
else
{
SetActiveTab (iActiveTab);
}
GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iActiveTab);
}
}
return TRUE;
}
//***************************************************************************************
void CBCGPBaseTabWnd::RemoveAllTabs ()
{
for (int i = 0; i < m_iTabsNum; i ++)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTab);
if (m_ToolTip.GetSafeHwnd () != NULL)
{
m_ToolTip.DelTool (this, pTab->m_iTabID);
}
if (m_bAutoDestoyWindow)
{
pTab->m_pWnd->DestroyWindow ();
}
delete pTab;
}
if (m_ToolTip.GetSafeHwnd () != NULL)
{
ASSERT (m_ToolTip.GetToolCount () == 0);
}
m_arTabs.RemoveAll ();
m_iTabsNum = 0;
m_iActiveTab = -1;
m_nNextTabID = 1;
RecalcLayout ();
GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, (UINT)-1);
}
//***************************************************************************************
int CBCGPBaseTabWnd::GetVisibleTabsNum () const
{
int nCount = 0;
for (int i = 0; i < m_iTabsNum; i++)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTab);
if (pTab->m_bVisible)
{
nCount++;
}
}
return nCount;
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::ShowTab(int iTab, BOOL bShow /*= TRUE*/, BOOL bRecalcLayout /*= TRUE*/,
BOOL bActivate)
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
TRACE(_T("ShowTab: illegal tab number %d\n"), iTab);
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
if (pTab->m_bVisible == bShow)
{
return TRUE;
}
int nVisibleCount = GetVisibleTabsNum ();
pTab->m_bVisible = bShow;
int iActiveTab = (bShow ? m_iActiveTab : -1);
if (!bShow)
{
//----------
// Hide tab:
//----------
if (m_bHideInactiveWnd)
{
ASSERT_VALID (pTab->m_pWnd);
pTab->m_pWnd->ShowWindow(SW_HIDE);
}
if (iTab == m_iActiveTab)
{
// Find the next best tab to be activated
for (int i = m_iTabsNum - 1; i >= 0; --i)
{
CBCGPTabInfo* pNextActiveTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pNextActiveTab);
if (i < iTab && iActiveTab >= 0)
{
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -