?? customtabctrl.h
字號:
}
bool IsHighlighted() const
{
return m_bHighlighted;
}
bool SetHighlighted(bool bHighlighted)
{
m_bHighlighted = bHighlighted;
return true;
}
bool CanClose() const
{
return m_bCanClose;
}
bool SetCanClose(bool bCanClose)
{
m_bCanClose = bCanClose;
return true;
}
// Methods:
public:
bool UsingImage() const
{
return (m_nImage >= 0);
}
bool UsingText() const
{
return (m_sText.GetLength() > 0);
}
bool UsingToolTip() const
{
return (m_sToolTip.GetLength() > 0);
}
BOOL InflateRect(int dx, int dy)
{
return ::InflateRect(&m_rcItem, dx, dy);
}
bool MatchItem(CCustomTabItem* pItem, DWORD eFlags) const
{
bool bMatch = true;
if(bMatch && (eFlags & CTFI_RECT) == CTFI_RECT)
{
bMatch = (TRUE == ::EqualRect(&m_rcItem, &pItem->m_rcItem));
}
if(bMatch && (eFlags & CTFI_IMAGE) == CTFI_IMAGE)
{
bMatch = (m_nImage == pItem->m_nImage);
}
if(bMatch && (eFlags & CTFI_TEXT) == CTFI_TEXT)
{
bMatch = (m_sText == pItem->m_sText);
}
if(bMatch && (eFlags & CTFI_TOOLTIP) == CTFI_TOOLTIP)
{
bMatch = (m_sToolTip == pItem->m_sToolTip);
}
if(bMatch && (eFlags & CTFI_HIGHLIGHTED) == CTFI_HIGHLIGHTED)
{
bMatch = (m_bHighlighted == pItem->m_bHighlighted);
}
if(bMatch && (eFlags & CTFI_CANCLOSE) == CTFI_CANCLOSE)
{
bMatch = (m_bCanClose == pItem->m_bCanClose);
}
if(bMatch)
{
*pItem = *this;
}
return bMatch;
}
};
// Derived Tab Item class that supports an HWND identifying a "tab view"
class CTabViewTabItem : public CCustomTabItem
{
protected:
typedef CCustomTabItem baseClass;
// Member variables (in addition to CCustomTabItem ones)
protected:
HWND m_hWndTabView;
public:
// NOTE: This is here for backwards compatibility.
// Use the new CTFI_TABVIEW instead
typedef enum FieldFlags
{
eCustomTabItem_TabView = CTFI_TABVIEW,
};
// Use CTFI_TABVIEW instead
#if (_MSC_VER >= 1300)
#pragma deprecated(eCustomTabItem_TabView)
#endif
// Constructors/Destructors
public:
CTabViewTabItem() :
m_hWndTabView(NULL)
{
}
CTabViewTabItem(const CTabViewTabItem& rhs)
{
*this = rhs;
}
virtual ~CTabViewTabItem()
{
}
const CTabViewTabItem& operator=(const CTabViewTabItem& rhs)
{
if(&rhs != this)
{
m_rcItem = rhs.m_rcItem;
m_nImage = rhs.m_nImage;
m_sText = rhs.m_sText;
m_sToolTip = rhs.m_sToolTip;
m_bHighlighted = rhs.m_bHighlighted;
m_bCanClose = rhs.m_bCanClose;
m_hWndTabView = rhs.m_hWndTabView;
}
return *this;
}
// Accessors
public:
HWND GetTabView() const
{
return m_hWndTabView;
}
bool SetTabView(HWND hWnd = NULL)
{
m_hWndTabView = hWnd;
return true;
}
// Methods:
public:
bool UsingTabView() const
{
return (m_hWndTabView != NULL);
}
bool MatchItem(CTabViewTabItem* pItem, DWORD eFlags) const
{
bool bMatch = true;
if(eFlags == CTFI_TABVIEW)
{
// Make the common case a little faster
// (searching only for a match to the "tab view" HWND)
bMatch = (m_hWndTabView == pItem->m_hWndTabView);
}
else
{
// Do an extensive comparison
bMatch = baseClass::MatchItem(pItem, eFlags);
if(bMatch && (eFlags & CTFI_TABVIEW) == CTFI_TABVIEW)
{
bMatch = (m_hWndTabView == pItem->m_hWndTabView);
}
}
if(bMatch)
{
*pItem = *this;
}
return bMatch;
}
};
typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CTCS_TOOLTIPS, 0> CCustomTabCtrlWinTraits;
template <class T, class TItem = CCustomTabItem, class TBase = CWindow, class TWinTraits = CCustomTabCtrlWinTraits>
class ATL_NO_VTABLE CCustomTabCtrl :
public CWindowImpl< T, TBase, TWinTraits >,
public COffscreenDrawRect< T >
{
public:
// Expose the item type (that's a template parameter to this base class)
typedef typename TItem TItem;
protected:
typedef CWindowImpl< T, TBase, TWinTraits > baseClass;
typedef COffscreenDrawRect< T > offscreenDrawClass;
#if (_ATL_VER < 0x0700)
// With ATL 7, CAtlArray was introduced which is better than
// CSimpleArray. Among other things, it supports inserting
// items in any place. If this code is compiled under ATL 7,
// we'll use the real CAtlArray. If this is compiled under ATL 3,
// we'll use a "fake" CAtlArray where we implement the
// functionality we're using that the real CAtlArray provides.
//
// Important! This isn't the real ATL 7 CAtlArray.
// We inherit from CSimpleArray as "protected", so that you
// can't call its versions of functions (so you have
// to use the CAtlArray style of functions)
template<typename E>
class CAtlArray : protected CSimpleArray<E>
{
protected:
typedef CAtlArray thisClass;
typedef CSimpleArray<E> baseClass;
public:
//Real CAtlArray: size_t GetCount() const throw();
size_t GetCount() const
{
return m_nSize;
}
//Real CAtlArray: void InsertAt( size_t iElement, INARGTYPE element, size_t nCount = 1 );
void InsertAt( size_t nIndex, E& element )
{
if(m_nSize == m_nAllocSize)
{
E* aT;
int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
aT = (E*)realloc(m_aT, nNewAllocSize * sizeof(E));
if(aT == NULL)
return; // FALSE;
m_nAllocSize = nNewAllocSize;
m_aT = aT;
}
memmove((void*)&m_aT[nIndex+1], (void*)&m_aT[nIndex], (m_nSize - nIndex ) * sizeof(E));
m_nSize++;
SetAtIndex(nIndex, element);
//return TRUE;
}
//Real CAtlArray: void RemoveAt( size_t iElement, size_t nCount = 1 );
void RemoveAt( size_t nIndex )
{
// This is an improvement over CSimpleArray::RemoveAt suggested
// by Jim Springfield on the ATL discussion list
m_aT[nIndex].~E();
if((int)nIndex != (m_nSize - 1))
{
memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(E));
}
m_nSize--;
//return TRUE;
}
//Real CAtlArray: const E& operator[]( size_t iElement ) const throw();
const E& operator[]( size_t iElement ) const
{
ATLASSERT( iElement < (size_t)m_nSize );
return( m_aT[iElement] );
}
//Real CAtlArray: E& operator[]( size_t iElement ) throw();
E& operator[]( size_t iElement )
{
ATLASSERT( iElement < (size_t)m_nSize );
return( m_aT[iElement] );
}
};
#endif // (_ATL_VER < 0x0700)
// Member variables
protected:
int m_iCurSel;
int m_iHotItem;
CTCSETTINGS m_settings;
CAtlArray< TItem* > m_Items;
CFont m_font;
CFont m_fontSel;
CImageList m_imageList;
CToolTipCtrl m_tooltip;
RECT m_rcTabItemArea;
RECT m_rcScrollLeft;
RECT m_rcScrollRight;
RECT m_rcCloseButton;
int m_iDragItem;
int m_iDragItemOriginal;
POINT m_ptDragOrigin;
HCURSOR m_hCursorMove;
HCURSOR m_hCursorNoDrop;
int m_iScrollOffset;
// Flags, internal state, etc.
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-------+-------+-------+-------+---+-----------+---------------+
// | FUT | MO | MD | HT |SR | SD | FLAGS |
// +-------+-------+-------+-------+---+-----------+---------------+
//
// FLAGS - boolean flags
// SD - Scroll delta. The number of pixels to move in a single scroll.
// Valid values are 0-63 (the value is bit shifted to/from position).
// SR - Scroll repeat speed. Valid values are no-repeat,
// slow repeat, normal repeat and fast repeat
// HT - Current hot tracked item (if its a tab, then m_iHotItem is the hot tab item)
// MD - Item under mouse when mouse button down message was sent
// but before mouse button up message is sent
// MO - Item current under mouse cursor
// FUT - Not used at this time, but reserved for the future.
DWORD m_dwState;
enum StateBits
{
// Flags
// bits = 0x000000ff
ectcMouseInWindow = 0x00000001,
ectcOverflowLeft = 0x00000002,
ectcOverflowRight = 0x00000004,
//ectcOverflowBottom = 0x00000002, // alias for vertical mode
//ectcOverflowTop = 0x00000004, // alias for vertical mode
ectcEnableRedraw = 0x00000008,
ectcDraggingItem = 0x00000010,
//ectcFlag20 = 0x00000020,
//ectcFlag40 = 0x00000040,
//ectcFlag80 = 0x00000080,
// Scroll
// bits = 0x0000ff00
ectcScrollDeltaMask = 0x00003f00, //0011 1111
ectcScrollDeltaShift = 8,
// We have to publicly expose these:
ectcScrollRepeat = 0x0000c000, //1100 0000
//ectcScrollRepeat_None = 0x00000000,
//ectcScrollRepeat_Slow = 0x00004000, //0100 0000
//ectcScrollRepeat_Normal = 0x00008000, //1000 0000
//ectcScrollRepeat_Fast = 0x0000c000, //1100 0000
// Hot Tracking
// bits = 0x000f0000
ectcHotTrack = 0x000f0000,
ectcHotTrack_CloseButton = 0x00010000,
ectcHotTrack_ScrollRight = 0x00020000,
ectcHotTrack_ScrollLeft = 0x00030000,
ectcHotTrack_TabItem = 0x00040000,
// Mouse Down
// bits = 0x00f00000
ectcMouseDown = 0x00f00000,
ectcMouseDownL_CloseButton = 0x00100000,
ectcMouseDownL_ScrollRight = 0x00200000,
ectcMouseDownL_ScrollLeft = 0x00300000,
ectcMouseDownL_TabItem = 0x00400000,
ectcMouseDownR_CloseButton = 0x00900000,
ectcMouseDownR_ScrollRight = 0x00a00000,
ectcMouseDownR_ScrollLeft = 0x00b00000,
ectcMouseDownR_TabItem = 0x00c00000,
// Mouse Over
// bits = 0x0f000000
ectcMouseOver = 0x0f000000,
ectcMouseOver_CloseButton = 0x01000000,
ectcMouseOver_ScrollRight = 0x02000000,
ectcMouseOver_ScrollLeft = 0x03000000,
ectcMouseOver_TabItem = 0x04000000,
};
enum ButtonToolTipIDs
{
ectcToolTip_Close = 0xFFFFFFF0,
ectcToolTip_ScrollRight = 0xFFFFFFF1,
ectcToolTip_ScrollLeft = 0xFFFFFFF2,
};
enum TimerIDs
{
ectcTimer_ScrollLeft = 0x00000010,
ectcTimer_ScrollRight = 0x00000020,
};
// Public enumerations
public:
enum ScrollRepeat
{
ectcScrollRepeat_None = 0x00000000,
ectcScrollRepeat_Slow = 0x00004000,
ectcScrollRepeat_Normal = 0x00008000,
ectcScrollRepeat_Fast = 0x0000c000,
};
// Constructors
public:
CCustomTabCtrl() :
m_iCurSel(-1),
m_iHotItem(-1),
m_dwState(0),
m_iDragItem(-1),
m_iDragItemOriginal(-1),
m_hCursorMove(NULL),
m_hCursorNoDrop(NULL),
m_iScrollOffset(0)
{
::ZeroMemory(&m_settings, sizeof(CTCSETTINGS));
::ZeroMemory(&m_ptDragOrigin, sizeof(POINT));
::SetRectEmpty(&m_rcTabItemArea);
::SetRectEmpty(&m_rcCloseButton);
::SetRectEmpty(&m_rcScrollLeft);
::SetRectEmpty(&m_rcScrollRight);
m_dwState |= ((40 << ectcScrollDeltaShift) & ectcScrollDeltaMask);
m_dwState |= ectcScrollRepeat_Normal;
m_dwState |= ectcEnableRedraw;
}
// Implementation
protected:
void InitializeTooltips(void)
{
ATLASSERT(!m_tooltip.IsWindow());
if(!m_tooltip.IsWindow())
{
// Be sure InitCommonControlsEx is called before this,
// with one of the flags that includes the tooltip control
m_tooltip.Create(m_hWnd, NULL, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP /* | TTS_BALLOON */, WS_EX_TOOLWINDOW);
if(m_tooltip.IsWindow())
{
m_tooltip.SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
m_tooltip.SetDelayTime(TTDT_INITIAL, ::GetDoubleClickTime());
m_tooltip.SetDelayTime(TTDT_AUTOPOP, ::GetDoubleClickTime() * 20);
m_tooltip.SetDelayTime(TTDT_RESHOW, ::GetDoubleClickTime() / 5);
}
}
}
void ActivateTooltips(BOOL bActivate = TRUE)
{
ATLASSERT(m_tooltip.IsWindow());
if(m_tooltip.IsWindow())
{
m_tooltip.Activate(bActivate);
}
}
void ClearCurrentHotTracking(bool bRedrawEffectedArea = true)
{
switch(m_dwState & ectcHotTrack)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -