⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 customtabctrl.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 5 页
字号:
	{
		return (LPCTSTR)m_sToolTip;
	}
	bool SetToolTip(LPCTSTR sNewText)
	{
		m_sToolTip = sNewText;
		return true;
	}

	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;
	}
};

#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)

namespace ATL {

template<typename E>
class CAtlArray : protected ATL::CSimpleArray<E>
{
protected:
	typedef CAtlArray thisClass;
	typedef ATL::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] );
	}

};

}; // namespace ATL

#endif // (_ATL_VER < 0x0700)



typedef ATL::CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CTCS_TOOLTIPS, 0> CCustomTabCtrlWinTraits;

template <class T, class TItem = CCustomTabItem, class TBase = ATL::CWindow, class TWinTraits = CCustomTabCtrlWinTraits>
class ATL_NO_VTABLE CCustomTabCtrl : 
	public ATL::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 ATL::CWindowImpl< T, TBase, TWinTraits > baseClass;
	typedef COffscreenDrawRect< T > offscreenDrawClass;

// Member variables
protected:
	int m_iCurSel;
	int m_iHotItem;
	CTCSETTINGS m_settings;
	ATL::CAtlArray< TItem* > m_Items;
	WTL::CFont m_font;
	WTL::CFont m_fontSel;
	WTL::CImageList m_imageList;
	WTL::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);
			}
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -