www.pudn.com > ÍøÂç¶Ë¿Ú¼àÊÓ.rar > 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;
}
if (pNextActiveTab->m_bVisible)
{
iActiveTab = i;
}
}
m_iActiveTab = -1;
}
}
// If there was no tab visible, activate this first one
if (bShow && nVisibleCount == 0)
{
iActiveTab = iTab;
}
if (bRecalcLayout)
{
RecalcLayout ();
}
if (iActiveTab >= 0 && !bShow && m_iActiveTab == -1 || bActivate || nVisibleCount == 0)
{
SetActiveTab (iActiveTab);
GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iActiveTab);
}
return TRUE;
}
//****************************************************************************************
CWnd* CBCGPBaseTabWnd::GetTabWnd (int iTab) const
{
if (iTab >= 0 && iTab < m_iTabsNum)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_pWnd;
}
else
{
return NULL;
}
}
//*********************************************************************************
CWnd* CBCGPBaseTabWnd::GetTabWndNoWrapper (int iTab) const
{
if (iTab >= 0 && iTab < m_iTabsNum)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
CBCGPDockingCBWrapper* pWrapper =
DYNAMIC_DOWNCAST (CBCGPDockingCBWrapper, pTab->m_pWnd);
if (pWrapper != NULL)
{
return pWrapper->GetWrappedWnd ();
}
return pTab->m_pWnd;
}
else
{
return NULL;
}
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::GetTabRect (int iTab, CRect& rect) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
if (!pTab->m_bVisible)
{
rect.SetRectEmpty ();
return FALSE;
}
rect = pTab->m_rect;
return TRUE;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::GetTabLabel (int iTab, CString& strLabel) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
strLabel = pTab->m_bIconOnly ? _T("") : pTab->m_strText;
return TRUE;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabLabel (int iTab, const CString& strLabel)
{
if (iTab < 0 || iTab >= m_iTabsNum || strLabel.IsEmpty ())
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
pTab->m_strText = strLabel;
if (m_ToolTip.GetSafeHwnd () != NULL)
{
m_ToolTip.UpdateTipText (strLabel, this, pTab->m_iTabID);
}
if (pTab->m_pWnd != NULL)
{
pTab->m_pWnd->SetWindowText (strLabel);
}
RecalcLayout();
if (iTab == m_iActiveTab)
{
//--------------------------------------------------
// Set text to the parent frame/docking control bar:
//--------------------------------------------------
CBCGPBaseTabbedBar* pTabControlBar =
DYNAMIC_DOWNCAST (CBCGPBaseTabbedBar, GetParent ());
if (pTabControlBar != NULL) // tabbed dock bar - redraw caption only in this case
{
// miniframe will take the text from the tab control bar
if (pTabControlBar->CanSetCaptionTextToTabName ())
{
pTabControlBar->SetWindowText (strLabel);
}
CWnd* pWndToUpdate = pTabControlBar;
if (!pTabControlBar->IsDocked ())
{
pWndToUpdate = pTabControlBar->GetParent ();
}
if (pWndToUpdate != NULL)
{
pWndToUpdate->RedrawWindow (NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
}
}
return TRUE;
}//********************************************************************************
UINT CBCGPBaseTabWnd::GetTabIcon (int iTab) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return (UINT) -1;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_uiIcon;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabIcon (int iTab, UINT uiIcon)
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
if (pTab->m_hIcon != NULL)
{
::DestroyIcon (pTab->m_hIcon);
}
pTab->m_uiIcon = uiIcon;
pTab->m_hIcon = NULL;
return TRUE;
}
//********************************************************************************
HICON CBCGPBaseTabWnd::GetTabHicon (int iTab) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return NULL;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_hIcon;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabHicon (int iTab, HICON hIcon)
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
if (pTab->m_hIcon != NULL)
{
::DestroyIcon (pTab->m_hIcon);
}
if (hIcon != NULL)
{
pTab->m_hIcon = ::CopyIcon (hIcon);
}
else
{
pTab->m_hIcon = NULL;
}
pTab->m_uiIcon = (UINT)-1;
m_sizeImage.cx = max (m_sizeImage.cx, globalData.m_sizeSmallIcon.cx);
m_sizeImage.cy = max (m_sizeImage.cy, globalData.m_sizeSmallIcon.cy);
return TRUE;
}
//******************************************************************************************
BOOL CBCGPBaseTabWnd::IsTabIconOnly (int iTab) const
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_bIconOnly;
};
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabIconOnly (int iTab, BOOL bIconOnly, BOOL bAlwaysShowToolTip)
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
pTab->m_bIconOnly = bIconOnly;
pTab->m_bAlwaysShowToolTip = bAlwaysShowToolTip;
RecalcLayout();
return TRUE;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::IsTabDetachable (int iTab) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_bIsDetachable;
}
//******************************************************************************************
BOOL CBCGPBaseTabWnd::EnableTabDetach (int iTab, BOOL bEnable)
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
pTab->m_bIsDetachable = bEnable;
return TRUE;
}
//******************************************************************************************
CWnd* CBCGPBaseTabWnd::GetActiveWnd () const
{
return m_iActiveTab == -1 ?
NULL :
((CBCGPTabInfo*) m_arTabs [m_iActiveTab])->m_pWnd;
}
//***************************************************************************************
int CBCGPBaseTabWnd::GetTabFromPoint (CPoint& pt) const
{
for (int i = 0; i < m_iTabsNum; i ++)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTab);
if (pTab->m_bVisible && pTab->m_rect.PtInRect (pt))
{
return i;
}
}
return -1;
}
//***************************************************************************************
int CBCGPBaseTabWnd::GetTabFromHwnd (HWND hwnd) const
{
for (int i = 0; i < m_iTabsNum; i ++)
{
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTab);
if (pTab->m_pWnd == NULL)
{
continue;
}
if (pTab->m_pWnd->GetSafeHwnd () == hwnd)
{
return i;
}
}
return -1;
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::IsTabVisible(int iTab) const
{
if (iTab < 0 || iTab >= m_iTabsNum)
{
TRACE(_T("IsTabVisible: illegal tab number %d\n"), iTab);
return FALSE;
}
const CBCGPTabInfo* pTab = (const CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID (pTab);
return pTab->m_bVisible;
}
//***************************************************************************************
int CBCGPBaseTabWnd::GetTabNumberToDetach (int nTabNum) const
{
return (nTabNum == -1 ? m_iActiveTab : nTabNum);
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::DetachTab (BCGP_DOCK_METHOD dockMethod, int nTabNum, BOOL bHide)
{
int nTabToDetach = GetTabNumberToDetach (nTabNum);
if (nTabToDetach < 0)
{
return FALSE;
}
ASSERT (nTabToDetach >= 0 && nTabToDetach < GetTabsNum ());
if (!IsTabDetachable (nTabToDetach))
{
return FALSE;
}
CBCGPControlBar* pDockingBar =
DYNAMIC_DOWNCAST (CBCGPControlBar, GetTabWnd (nTabToDetach));
if (pDockingBar == NULL)
{
return FALSE;
}
ASSERT_VALID (pDockingBar);
if (!pDockingBar->CanFloat ())
{
return FALSE;
}
CRect rectFloat; rectFloat.SetRectEmpty ();
if (!pDockingBar->OnBeforeFloat (rectFloat, dockMethod))
{
return FALSE;
}
if (dockMethod == DM_MOUSE)
{
CPoint ptMouse;
GetCursorPos (&ptMouse);
CPoint ptHotDelta = m_ptHot - ptMouse;
CSize szSencitivity = CBCGPDockingControlBar::GetDragSencitivity ();
if (abs (ptHotDelta.x) < szSencitivity.cx && abs (ptHotDelta.y) < szSencitivity.cy)
{
return FALSE;
}
}
if (pDockingBar != NULL && pDockingBar->CanBeAttached ())
{
BCGP_DOCK_TYPE dockType = pDockingBar->GetDockMode ();
CBCGPBaseTabbedBar* pParent = DYNAMIC_DOWNCAST (CBCGPBaseTabbedBar, GetParent ());
CBCGPMiniFrameWnd* pMiniFrame = pParent == NULL ? NULL : pParent->GetParentMiniFrame ();
if (pParent != NULL)
{
if (pDockingBar->IsKindOf (RUNTIME_CLASS (CBCGPDockingControlBar)))
{
((CBCGPDockingControlBar*) pDockingBar)->EnableGripper (TRUE);
}
if (!bHide && dockType == DT_STANDARD && dockMethod == DM_MOUSE)
{
bHide = TRUE;
}
if (/*!bHide && */nTabToDetach != m_iActiveTab)
{
pDockingBar->ShowWindow (SW_SHOW);
}
pParent->FloatTab (pDockingBar, nTabToDetach, dockMethod, bHide);
if (GetTabsNum () == 0)
{
if (pMiniFrame != NULL)
{
pMiniFrame->RemoveControlBar (pParent, TRUE);
}
else
{
if (pParent->AllowDestroyEmptyTabbedBar ())
{
pParent->DestroyWindow ();
}
else
{
ShowWindow (SW_HIDE);
}
}
}
else if (GetVisibleTabsNum () == 0)
{
pParent->ShowControlBar (FALSE, FALSE, FALSE);
}
RecalcLayout ();
}
CBCGPMiniFrameWnd* pParentFrame = pDockingBar->GetParentMiniFrame ();
if (dockType == DT_STANDARD && dockMethod == DM_MOUSE)
{
if (pParentFrame != NULL)
{
ReleaseCapture ();
pParentFrame->SetFocus ();
GetParent ()->SendMessage (WM_IDLEUPDATECMDUI);
}
}
m_bReadyToDetach = FALSE;
HWND hWndToDestroy = NULL;
if (GetTabsNum () == 1 && m_bHideSingleTab)
{
CRect rectWnd;
pParent->GetWindowRect (rectWnd);
CBCGPDockingControlBar* pDockingBar =
DYNAMIC_DOWNCAST (CBCGPDockingControlBar, GetTabWnd (0));
pParent->InsertControlBar (pDockingBar, pParent);
pParent->ReplaceControlBar (pDockingBar, dockMethod);
pDockingBar->SetBarAlignment (pParent->GetCurrentAlignment ());
RemoveTab (0);
CWnd* pNewParent = (pMiniFrame == NULL) ? pParent->GetDockSite ()
: pMiniFrame;
pDockingBar->EnableGripper (TRUE);
pNewParent->ScreenToClient (rectWnd);
pDockingBar->SetParent (pNewParent);
pDockingBar->SetWindowPos (NULL, rectWnd.left, rectWnd.top,
rectWnd.Width (), rectWnd.Height (),
SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
pDockingBar->ShowControlBar (TRUE, FALSE, FALSE);
pParent->ShowWindow (SW_HIDE);
pDockingBar->GetParent ()->InvalidateRect (NULL);
pDockingBar->GetParent ()->UpdateWindow ();
hWndToDestroy = pParent->GetSafeHwnd ();
}
if (dockMethod == DM_MOUSE && pParentFrame != NULL)
{
ASSERT_VALID (pParentFrame);
if (dockType == DT_STANDARD)
{
pParentFrame->EnterDragMode (hWndToDestroy);
pParentFrame->MoveDragFrame ();
}
else if (dockType == DT_IMMEDIATE)
{
pParentFrame->SetFocus ();
}
}
return TRUE;
}
return FALSE;
}
//***************************************************************************************
void CBCGPBaseTabWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDown(nFlags, point);
int iHighlighted = m_iHighlighted;
if (iHighlighted >= 0)
{
BOOL bTabWasMoved = FALSE;
if (!ActivateOnBtnUp ())
{
int nTab = GetTabFromPoint (point);
SetActiveTab (point);
bTabWasMoved = (nTab != GetTabFromPoint (point));
m_iHighlighted = -1;
ReleaseCapture ();
}
else
{
m_iPressed = m_iHighlighted;
}
if (iHighlighted != m_iActiveTab)
{
InvalidateTab (iHighlighted);
}
if (!bTabWasMoved)
{
EnterDragMode ();
}
}
}
//***************************************************************************************
void CBCGPBaseTabWnd::EnterDragMode ()
{
m_bReadyToDetach = TRUE;
SetCapture ();
GetCursorPos (&m_ptHot);
CRect rectTab;
GetTabRect (m_iActiveTab, rectTab);
m_iTabBeforeDrag = m_iActiveTab;
ClientToScreen (rectTab);
m_nOffsetFromTabLeft = m_ptHot.x - rectTab.left;
}
//***************************************************************************************
void CBCGPBaseTabWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDblClk(nFlags, point);
if (m_bIsInPlaceEdit)
{
int iTab = GetTabFromPoint (point);
if (iTab == GetActiveTab())
{
if (StartRenameTab (iTab))
return;
}
}
else
{
CWnd* pWndTarget = FindTargetWnd (point);
if (pWndTarget == NULL)
{
DetachTab (DM_DBL_CLICK);
}
}
}
//***************************************************************************************
void CBCGPBaseTabWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_iTabBeforeDrag != m_iActiveTab)
{
CWnd* pWndParent = GetParent ();
ASSERT_VALID (pWndParent);
pWndParent->SendMessage (BCGM_ON_MOVE_TAB, m_iTabBeforeDrag, m_iActiveTab);
if (pWndParent->IsKindOf (RUNTIME_CLASS (CBCGPBaseTabbedBar)))
{
pWndParent = BCGPGetParentFrame (pWndParent);
if (pWndParent != NULL)
{
pWndParent->SendMessage (BCGM_ON_MOVE_TAB, m_iTabBeforeDrag, m_iActiveTab);
}
}
}
if (m_bReadyToDetach)
{
m_bReadyToDetach = FALSE;
ReleaseCapture ();
if (!ActivateOnBtnUp ())
{
m_iPressed = -1;
m_iHighlighted = -1;
}
}
if (ActivateOnBtnUp ())
{
bool bNewActiveTab = m_iActiveTab != m_iHighlighted;
if (m_iHighlighted == m_iPressed)
{
SetActiveTab (point);
}
int iHighlighted = m_iHighlighted;
int iPressed = m_iPressed;
m_iPressed = -1;
if (!IsOneNoteStyle ())
{
m_iHighlighted = -1;
}
ReleaseCapture ();
if (bNewActiveTab)
{
InvalidateTab (iHighlighted);
if (iPressed != iHighlighted)
{
InvalidateTab (iPressed);
}
}
}
CWnd::OnLButtonUp(nFlags, point);
}
//***************************************************************************************
void CBCGPBaseTabWnd::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd::OnMouseMove(nFlags, point);
int iPrevHighlighted = m_iHighlighted;
m_iHighlighted = GetTabFromPoint (point);
if (m_iPressed >= 0 && m_iHighlighted != m_iPressed)
{
m_iHighlighted = -1;
}
if (m_iHighlighted != iPrevHighlighted && m_bHighLightTabs)
{
if (iPrevHighlighted < 0)
{
if (m_iHighlighted >= 0)
{
SetCapture ();
}
}
else
{
if (m_iHighlighted < 0 && m_iPressed < 0)
{
if (!m_bReadyToDetach)
{
ReleaseCapture ();
}
}
}
InvalidateTab (m_iHighlighted);
InvalidateTab (iPrevHighlighted);
}
if (m_bReadyToDetach)
{
int nNumTabs = m_iTabsNum; // how many tabs before detch
// try to rearrange tabs if their number > 1
if (IsPtInTabArea (point) && nNumTabs > 1 && m_bEnableTabSwap)
{
CRect rectTab;
int nTabNum = GetTabFromPoint (point);
if (nTabNum != m_iActiveTab && nTabNum != -1)
{
int nSecondTab = m_iActiveTab;
SwapTabs (nTabNum, nSecondTab);
RecalcLayout ();
SetActiveTab (nTabNum);
int nCurrTabNum = GetTabFromPoint (point);
if (nCurrTabNum != nTabNum)
{
GetTabRect (nTabNum, rectTab);
CPoint ptCursorNewPos = point;
ptCursorNewPos.x = rectTab.left + m_nOffsetFromTabLeft;
ClientToScreen (&ptCursorNewPos);
SetCursorPos (ptCursorNewPos.x, ptCursorNewPos.y);
}
}
return;
}
if (IsPtInTabArea (point))
{
return;
}
BOOL bDetachSucceeded = DetachTab (DM_MOUSE);
if (bDetachSucceeded && nNumTabs <= 2)
{
// last tab was detached successfully - run out, because the control
// jas been destroyed
return;
}
if (bDetachSucceeded)
{
m_bReadyToDetach = FALSE;
}
return;
}
}
//************************************************************************************
void CBCGPBaseTabWnd::OnCancelMode()
{
CWnd::OnCancelMode();
if (m_iHighlighted >= 0)
{
int iTab = m_iHighlighted;
ReleaseCapture ();
m_iHighlighted = -1;
m_iPressed = -1;
InvalidateTab (iTab);
}
if (m_pInPlaceEdit != NULL)
{
m_pInPlaceEdit->DestroyWindow ();
delete m_pInPlaceEdit;
m_pInPlaceEdit = NULL;
m_iEditedTab = -1;
ReleaseCapture ();
}
}
//************************************************************************************
void CBCGPBaseTabWnd::InvalidateTab (int iTab)
{
ASSERT_VALID (this);
if (iTab < 0)
{
return;
}
CRect rectTab;
if (GetTabRect (iTab, rectTab))
{
InvalidateRect (rectTab);
UpdateWindow ();
}
}
//*************************************************************************************
BOOL CBCGPBaseTabWnd::SetActiveTab (CPoint point)
{
ASSERT_VALID (this);
if (m_iHighlighted < 0)
{
return FALSE;
}
CWnd* pWndParent = GetParent ();
ASSERT_VALID (pWndParent);
if (m_iHighlighted != m_iActiveTab && IsPtInTabArea (point))
{
m_iLastActiveTab = m_iActiveTab;
SetActiveTab (m_iHighlighted);
pWndParent->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iHighlighted);
}
return TRUE;
}
//*************************************************************************************
void CBCGPBaseTabWnd::OnDestroy()
{
CleanUp ();
CWnd::OnDestroy();
}
//*************************************************************************************
int CBCGPBaseTabWnd::FindTabInfo (int nBarID, CBCGPTabInfo** ppTabInfo)
{
*ppTabInfo = NULL;
for (int i = 0; i < m_arTabs.GetSize (); i++)
{
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs.GetAt (i);
ASSERT_VALID (pTabInfo);
if (pTabInfo->m_pWnd != NULL && pTabInfo->m_pWnd->GetDlgCtrlID () == nBarID)
{
*ppTabInfo = pTabInfo;
return i;
}
}
return NULL;
}
//*************************************************************************************
void CBCGPBaseTabWnd::ApplyRestoredTabInfo (BOOL bUseTabIndexes)
{
CBCGPDockManager* pDockManager = globalUtils.GetDockManager (BCGPGetParentFrame (this));
ASSERT_VALID (pDockManager);
for (POSITION pos = m_lstRestoredTabInfo.GetHeadPosition (); pos != NULL;)
{
CBCGPRestoredTabInfo tabInfo = m_lstRestoredTabInfo.GetNext (pos);
CBCGPTabInfo* pCurrTabInfo = NULL;
FindTabInfo (tabInfo.m_nControlBarID, &pCurrTabInfo);
if (pCurrTabInfo != NULL)
{
continue;
}
CBCGPDockingControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPDockingControlBar,
pDockManager->FindBarByID (tabInfo.m_nControlBarID, TRUE));
if (pBar != NULL)
{
if (pBar->IsTabbed ())
{
CBCGPBaseTabWnd* pTabWnd = (CBCGPBaseTabWnd*) pBar->GetParent ();
CBCGPBaseTabbedBar* pTabBar = (CBCGPBaseTabbedBar*) pTabWnd->GetParent ();
ASSERT_VALID (pTabBar);
pBar->SetParent (GetParent ());
pTabBar->RemoveControlBar (pBar);
if (pBar->IsKindOf (RUNTIME_CLASS (CBCGPDockingControlBar)))
{
((CBCGPDockingControlBar*) pBar)->EnableGripper (TRUE);
}
pBar->ShowWindow (SW_SHOW);
}
if (pBar->IsAutoHideMode ())
{
pBar->SetAutoHideMode (FALSE, CBRS_ALIGN_ANY);
}
CBCGPMiniFrameWnd* pMiniFrame = pBar->GetParentMiniFrame ();
if (pMiniFrame != NULL)
{
pMiniFrame->RemoveControlBar (pBar);
}
pBar->SetParent (GetParent ());
CBCGPBaseTabbedBar* pTabbedBar =
DYNAMIC_DOWNCAST (CBCGPBaseTabbedBar, GetParent ());
pBar->AttachToTabWnd (pTabbedBar, DM_SHOW, FALSE);
}
}
int nTabIdx = 0;
for (pos = m_lstRestoredTabInfo.GetHeadPosition (); pos != NULL; nTabIdx++)
{
CBCGPRestoredTabInfo tabInfo = m_lstRestoredTabInfo.GetNext (pos);
CBCGPTabInfo* pCurrTabInfo = NULL;
int nCurIdx = FindTabInfo (tabInfo.m_nControlBarID, &pCurrTabInfo);
if (pCurrTabInfo == NULL)
{
continue;
}
pCurrTabInfo->m_strText = tabInfo.m_strText;
pCurrTabInfo->m_bVisible = tabInfo.m_bVisible;
pCurrTabInfo->m_clrText = tabInfo.m_clrText;
pCurrTabInfo->m_clrBack = tabInfo.m_clrBack;
pCurrTabInfo->m_bIsDetachable = tabInfo.m_bDetachable;
if (bUseTabIndexes && nCurIdx != nTabIdx)
{
SwapTabs (nCurIdx, nTabIdx);
if (pCurrTabInfo->m_pWnd != NULL && nTabIdx == m_nRestoredActiveTabID)
{
pCurrTabInfo->m_pWnd->ShowWindow (SW_SHOW);
}
}
}
if (!SetActiveTab (m_nRestoredActiveTabID))
{
SetActiveTab (0);
}
RecalcLayout ();
}
//*************************************************************************************
void CBCGPBaseTabWnd::Serialize (CArchive& ar)
{
int nTabCount = 0;
if (ar.IsLoading ())
{
m_lstRestoredTabInfo.RemoveAll ();
ar >> nTabCount;
for (int i = 0; i < nTabCount; i++)
{
CBCGPRestoredTabInfo tabInfo;
ar >> tabInfo.m_strText;
ar >> tabInfo.m_bVisible;
ar >> tabInfo.m_nControlBarID;
ar >> tabInfo.m_bDetachable;
ar >> tabInfo.m_clrText;
ar >> tabInfo.m_clrBack;
m_lstRestoredTabInfo.AddTail (tabInfo);
}
ar >> m_nRestoredActiveTabID;
int nLoc = 0;
ar >> nLoc;
m_locationRestored = (Location) nLoc;
}
else
{
nTabCount = m_arTabs.GetSize ();
ar << nTabCount;
for (int i = 0; i < nTabCount; i++)
{
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs.GetAt (i);
ASSERT_VALID (pTabInfo);
ar << pTabInfo->m_strText;
ar << pTabInfo->m_bVisible;
ASSERT_VALID (pTabInfo->m_pWnd);
ar << pTabInfo->m_pWnd->GetDlgCtrlID ();
ar << pTabInfo->m_bIsDetachable;
ar << pTabInfo->m_clrText;
ar << pTabInfo->m_clrBack;
}
ar << m_iActiveTab;
ar << m_location;
}
}
//***************************************************************************************
void CBCGPBaseTabWnd::SwapTabs (int nFisrtTabID, int nSecondTabID)
{
CBCGPTabInfo* pTabInfoFirst = (CBCGPTabInfo*) m_arTabs.GetAt (nFisrtTabID);
CBCGPTabInfo* pTabInfoSecond = (CBCGPTabInfo*) m_arTabs.GetAt (nSecondTabID);
m_arTabs.SetAt (nFisrtTabID, pTabInfoSecond);
m_arTabs.SetAt (nSecondTabID, pTabInfoFirst);
}
//***************************************************************************************
void CBCGPBaseTabWnd::MoveTab(int nSource, int nDest) // by Walter Meerschaert
{
CBCGPTabInfo* pSource = (CBCGPTabInfo*) m_arTabs [nSource];
CBCGPTabInfo* pActive = (CBCGPTabInfo*) m_arTabs [m_iActiveTab];
ASSERT (nDest < m_arTabs.GetSize ());
if (nDest == -1)
{
m_arTabs.Add (pSource);
m_arTabs.RemoveAt (nSource);
}
else
{
m_arTabs.RemoveAt (nSource);
m_arTabs.InsertAt (nDest, pSource);
}
for (int iTab = 0; iTab < m_arTabs.GetSize(); iTab++)
{
if (pActive == (CBCGPTabInfo*) m_arTabs [iTab])
{
if (iTab != m_iActiveTab)
{
SetActiveTab (iTab);
GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iActiveTab);
}
break;
}
}
RecalcLayout ();
}
//***************************************************************************************
CWnd* CBCGPBaseTabWnd::CreateWrapper (CWnd* pWndToWrap, LPCTSTR lpszTabLabel, BOOL bDetachable)
{
ASSERT_VALID (pWndToWrap);
if (pWndToWrap->IsKindOf (RUNTIME_CLASS (CBCGPDockingControlBar)) ||
!bDetachable || !m_bEnableWrapping)
{
return pWndToWrap;
}
CBCGPDockingCBWrapper* pWrapper = NULL;
if (m_pDockingBarWrapperRTC != NULL)
{
pWrapper = DYNAMIC_DOWNCAST (CBCGPDockingCBWrapper,
m_pDockingBarWrapperRTC->CreateObject ());
}
else
{
pWrapper = new CBCGPDockingCBWrapper;
}
ASSERT_VALID (pWrapper);
CRect rectInit (pWrapper->m_rectInitial);
// create will alter the runtime class, but here we have to save it
// and set back after create
CRuntimeClass* pSaveRTC = pWrapper->GetTabbedControlBarRTC ();
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
if (pWndToWrap->IsKindOf (RUNTIME_CLASS (CBCGPBaseControlBar)))
{
dwStyle |= ((CBCGPBaseControlBar*) pWndToWrap)->GetBarStyle ();
}
if (!pWrapper->Create (lpszTabLabel, this, rectInit, TRUE, (UINT) pWndToWrap->GetDlgCtrlID (),
dwStyle))
{
delete pWrapper;
TRACE0 ("Unable to create CBCGPDockingCBWrapper. \n");
return pWndToWrap;
}
pWrapper->EnableGripper (FALSE);
pWrapper->SetWrappedWnd (pWndToWrap);
pWrapper->m_recentDockInfo.m_rectRecentFloatingRect = rectInit;
if (pSaveRTC != NULL)
{
pWrapper->SetTabbedControlBarRTC (pSaveRTC);
}
return pWrapper;
}
//*************************************************************************************
BOOL CBCGPBaseTabWnd::StartRenameTab (int iTab)
{
ASSERT_VALID (this);
ASSERT (GetSafeHwnd () != NULL);
if (!m_bIsInPlaceEdit)
{
return FALSE;
}
if (iTab < 0 || iTab >= m_arTabs.GetSize ())
{
return FALSE;
}
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs.GetAt (iTab);
ASSERT (m_pInPlaceEdit == NULL);
m_pInPlaceEdit = new CEdit;
ASSERT_VALID (m_pInPlaceEdit);
CRect rectEdit = pTabInfo->m_rect;
CalcRectEdit (rectEdit);
if (!m_pInPlaceEdit->Create (WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rectEdit,
this, 1))
{
delete m_pInPlaceEdit;
m_pInPlaceEdit = NULL;
return FALSE;
}
m_pInPlaceEdit->SetWindowText (pTabInfo->m_strText);
m_pInPlaceEdit->SetFont (&globalData.fontRegular);
m_pInPlaceEdit->SetSel (0, -1, TRUE);
m_pInPlaceEdit->SetFocus ();
m_iEditedTab = iTab;
SetCapture ();
return TRUE;
}
//**************************************************************************************
BOOL CBCGPBaseTabWnd::PreTranslateMessage(MSG* pMsg)
{
if (m_pInPlaceEdit != NULL)
{
if (pMsg->message >= WM_KEYFIRST &&
pMsg->message <= WM_KEYLAST)
{
switch (pMsg->wParam)
{
case VK_RETURN:
if (!RenameTab ())
{
MessageBeep ((UINT)-1);
return TRUE;
}
// Slide down!
case VK_ESCAPE:
m_pInPlaceEdit->DestroyWindow ();
delete m_pInPlaceEdit;
m_pInPlaceEdit = NULL;
m_iEditedTab = -1;
ReleaseCapture ();
break;
default:
return FALSE;
}
return TRUE;
}
else if (pMsg->message >= WM_MOUSEFIRST &&
pMsg->message <= WM_MOUSELAST)
{
CRect rectEdit;
m_pInPlaceEdit->GetClientRect (rectEdit);
m_pInPlaceEdit->MapWindowPoints (this, rectEdit);
CPoint ptCursor;
::GetCursorPos (&ptCursor);
ScreenToClient (&ptCursor);
if (rectEdit.PtInRect (ptCursor))
{
m_pInPlaceEdit->SendMessage (pMsg->message, pMsg->wParam, pMsg->lParam);
}
else if (pMsg->message != WM_MOUSEMOVE)
{
m_pInPlaceEdit->DestroyWindow ();
delete m_pInPlaceEdit;
m_pInPlaceEdit = NULL;
m_iEditedTab = -1;
ReleaseCapture ();
}
return TRUE;
}
else
{
return FALSE;
}
}
return CWnd::PreTranslateMessage(pMsg);
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::RenameTab ()
{
ASSERT_VALID (this);
ASSERT (m_bIsInPlaceEdit);
if (m_pInPlaceEdit == NULL)
{
ASSERT (FALSE);
return FALSE;
}
CString strName;
m_pInPlaceEdit->GetWindowText (strName);
if (!strName.IsEmpty () &&
OnRenameTab (m_iEditedTab, strName) &&
GetParent ()->SendMessage (BCGM_ON_RENAME_TAB, m_iEditedTab,
(LPARAM)(LPCTSTR) strName) == 0)
{
return SetTabLabel (m_iEditedTab, strName);
}
return FALSE;
}
//***********************************************************************************
void CBCGPBaseTabWnd::SetActiveTabTextColor (COLORREF clr)
{
m_clrActiveTabFg = clr;
}
//***********************************************************************************
void CBCGPBaseTabWnd::SetActiveTabColor (COLORREF clr)
{
m_clrActiveTabBk = clr;
if (m_brActiveTab.GetSafeHandle () != NULL)
{
m_brActiveTab.DeleteObject ();
}
m_brActiveTab.CreateSolidBrush (GetActiveTabColor ());
}
//*********************************************************************************
COLORREF CBCGPBaseTabWnd::GetTabBkColor (int iTab) const
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return (COLORREF)-1;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
COLORREF color = pTab->m_clrBack;
if (color == (COLORREF)-1 && m_bIsAutoColor)
{
color = m_arAutoColors [iTab % m_arAutoColors.GetSize ()];
pTab->m_clrBack = color;
}
return color;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabBkColor (int iTab, COLORREF color)
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
pTab->m_clrBack = color;
return TRUE;
}
//*********************************************************************************
COLORREF CBCGPBaseTabWnd::GetTabTextColor (int iTab) const
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return (COLORREF)-1;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
return pTab->m_clrText;
}
//*********************************************************************************
BOOL CBCGPBaseTabWnd::SetTabTextColor (int iTab, COLORREF color)
{
ASSERT_VALID (this);
if (iTab < 0 || iTab >= m_iTabsNum)
{
return FALSE;
}
CBCGPTabInfo* pTab = (CBCGPTabInfo*) m_arTabs [iTab];
ASSERT_VALID(pTab);
pTab->m_clrText = color;
return TRUE;
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::SetImageList (UINT uiID, int cx, COLORREF clrTransp)
{
CBitmap bmp;
if (!bmp.LoadBitmap (uiID))
{
TRACE(_T("CBCGPTabWnd::SetImageList Can't load bitmap: %x\n"), uiID);
return FALSE;
}
BITMAP bmpObj;
bmp.GetBitmap (&bmpObj);
UINT nFlags = (clrTransp == (COLORREF) -1) ? 0 : ILC_MASK;
switch (bmpObj.bmBitsPixel)
{
case 4:
default:
nFlags |= ILC_COLOR4;
break;
case 8:
nFlags |= ILC_COLOR8;
break;
case 16:
nFlags |= ILC_COLOR16;
break;
case 24:
nFlags |= ILC_COLOR24;
break;
case 32:
nFlags |= ILC_COLOR32;
break;
}
m_Images.Create (cx, bmpObj.bmHeight, nFlags, 0, 0);
m_Images.Add (&bmp, clrTransp);
m_sizeImage = CSize (cx, bmpObj.bmHeight);
SetTabsHeight ();
return TRUE;
}
//***************************************************************************************
BOOL CBCGPBaseTabWnd::SetImageList (HIMAGELIST hImageList)
{
ASSERT (hImageList != NULL);
ASSERT (m_Images.GetSafeHandle () == NULL);
CImageList* pImageList = CImageList::FromHandle (hImageList);
if (pImageList == NULL)
{
ASSERT (FALSE);
return FALSE;
}
IMAGEINFO info;
pImageList->GetImageInfo (0, &info);
CRect rectImage = info.rcImage;
m_sizeImage = rectImage.Size ();
m_hImageList = hImageList;
SetTabsHeight ();
return TRUE;
}
//************************************************************************************
void CBCGPBaseTabWnd::SetTabsHeight ()
{
m_nTabsHeight = (max (m_sizeImage.cy + 2 * CBCGPBaseTabWnd::TAB_IMAGE_MARGIN,
globalData.GetTextHeight () + 2 * CBCGPBaseTabWnd::TAB_TEXT_MARGIN));
}
//*********************************************************************************
void CBCGPBaseTabWnd::HideSingleTab (BOOL bHide)
{
if (m_bHideSingleTab == bHide)
{
return;
}
m_bHideSingleTab = bHide;
if (GetSafeHwnd () != NULL)
{
RecalcLayout ();
}
}
//*********************************************************************************
CWnd* CBCGPBaseTabWnd::GetFirstVisibleTab (int& iTabNum)
{
for (int i = 0; i < m_iTabsNum; i++)
{
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTabInfo);
if (pTabInfo->m_bVisible)
{
iTabNum = i;
return pTabInfo->m_pWnd;
}
}
iTabNum = -1;
return NULL;
}
//********************************************************************************
CWnd* CBCGPBaseTabWnd::GetLastVisibleTab (int& iTabNum)
{
for (int i = m_iTabsNum - 1; i >= 0; i++)
{
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs [i];
ASSERT_VALID (pTabInfo);
if (pTabInfo->m_bVisible)
{
iTabNum = i;
return pTabInfo->m_pWnd;
}
}
iTabNum = -1;
return NULL;
}
//********************************************************************************
void CBCGPBaseTabWnd::SetDrawNoPrefix (BOOL bNoPrefix, BOOL bRedraw)
{
ASSERT_VALID (this);
m_bLabelNoPrefix = bNoPrefix;
if (bRedraw && GetSafeHwnd () != NULL)
{
RedrawWindow ();
}
}
//*******************************************************************************
int CBCGPBaseTabWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (BCGPGetParentFrame (this) == NULL)
{
m_bEnableWrapping = FALSE;
}
_AFX_THREAD_STATE* pState = AfxGetThreadState();
if (pState->m_bNeedTerm) // AfxOleInit was called
{
#ifndef BCG_NO_CUSTOMIZATION
m_DropTarget.Register (this);
#endif // BCG_NO_CUSTOMIZATION
}
return 0;
}
//*******************************************************************************
CSize CBCGPBaseTabWnd::GetMaxWindowSize () const
{
CSize sizeMax (0, 0);
int nTabCount = m_arTabs.GetSize ();
for (int i = 0; i < nTabCount; i++)
{
CBCGPTabInfo* pTabInfo = (CBCGPTabInfo*) m_arTabs.GetAt (i);
ASSERT_VALID (pTabInfo);
if (pTabInfo->m_pWnd != NULL)
{
CSize sizeCurr (0, 0);
if (pTabInfo->m_pWnd->IsKindOf (RUNTIME_CLASS (CBCGPBaseControlBar)))
{
CBCGPBaseControlBar* pBar =
DYNAMIC_DOWNCAST (CBCGPBaseControlBar, pTabInfo->m_pWnd);
if (pBar != NULL)
{
sizeCurr = pBar->CalcFixedLayout (FALSE, TRUE);
}
}
else
{
CRect rectWnd;
pTabInfo->m_pWnd->GetWindowRect (rectWnd);
sizeCurr = rectWnd.Size ();
}
sizeMax.cx = max (sizeCurr.cx, sizeMax.cx);
sizeMax.cy = max (sizeCurr.cy, sizeMax.cy);
}
}
return sizeMax;
}
//**********************************************************************************
void CBCGPBaseTabWnd::EnableAutoColor (BOOL bEnable/* = TRUE*/)
{
m_bIsAutoColor = bEnable;
InitAutoColors ();
if (GetSafeHwnd () != NULL)
{
RedrawWindow ();
}
}
//***********************************************************************************
void CBCGPBaseTabWnd::InitAutoColors ()
{
if (!m_bIsDefaultAutoColor)
{
return;
}
m_arAutoColors.RemoveAll ();
if (globalData.m_nBitsPerPixel > 8)
{
m_arAutoColors.Add (RGB (148, 175, 230));
m_arAutoColors.Add (RGB (255, 219, 117));
m_arAutoColors.Add (RGB (189, 205, 159));
m_arAutoColors.Add (RGB (240, 158, 159));
m_arAutoColors.Add (RGB (186, 166, 225));
m_arAutoColors.Add (RGB (154, 191, 180));
m_arAutoColors.Add (RGB (247, 182, 131));
m_arAutoColors.Add (RGB (213, 164, 187));
}
else
{
m_arAutoColors.Add (RGB (0, 255, 0));
m_arAutoColors.Add (RGB (0, 255, 255));
m_arAutoColors.Add (RGB (255, 0, 255));
m_arAutoColors.Add (RGB (192, 192, 192));
m_arAutoColors.Add (RGB (255, 255, 0));
}
}
//*************************************************************************************
void CBCGPBaseTabWnd::OnSysColorChange()
{
CWnd::OnSysColorChange();
InitAutoColors ();
}
//************************************************************************************
void CBCGPBaseTabWnd::SetAutoColors (const CArray& arColors)
{
m_arAutoColors.RemoveAll ();
if (arColors.GetSize () == 0)
{
m_bIsDefaultAutoColor = TRUE;
InitAutoColors ();
}
else
{
m_bIsDefaultAutoColor = FALSE;
for (int i = 0; i < arColors.GetSize (); i++)
{
m_arAutoColors.Add (arColors [i]);
}
}
if (GetSafeHwnd () != NULL)
{
RedrawWindow ();
}
}
//*********************************************************************************
void CBCGPBaseTabWnd::SetLocation (Location location)
{
ASSERT_VALID (this);
m_location = location;
RecalcLayout ();
if (GetSafeHwnd () != NULL)
{
GetParent ()->RedrawWindow (NULL, NULL,
RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
}
}