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

📄 flyingtabs.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
字号:
// Copyright (c) 2002
// Sergey Klimov (kidd@ukr.net)

#ifndef __WTL_DW__FLYING_TABS_H__
#define __WTL_DW__FLYING_TABS_H__

#include <cassert>
#include <vector>
#include <queue>
#include <algorithm>
#include <functional>

#include "DDTracker.h"

// NOTE: See CustomTabCtrl.h and DotNetTabCtrl.h for copyright information.
// Please download the latest versions of these files from from The Codeproject article
// "Custom Tab Controls, Tabbed Frame and Tabbed MDI" by Daniel Bowen (dbowen@es.com)
// http://www.codeproject.com/wtl/TabbingFramework.asp

#ifndef __ATLGDIX_H__
	#error FlyingTabs.h requires atlgdix.h to be included first
#endif
#ifndef __CUSTOMTABCTRL_H__
	#error FlyingTabs.h requires CustomTabCtrl.h to be included first
#endif
#ifndef __DOTNET_TABCTRL_H__
	#error FlyingTabs.h requires DotNetTabCtrl.h to be included first
#endif

namespace dockwins{

#define CTCN_TABLEAVCTRL CTCN_LAST-1

#ifndef CTCS_VERTICAL
#define CTCS_VERTICAL TCS_VERTICAL
#endif

class CFlyingTabCtrl :
	public CDotNetTabCtrlImpl<CFlyingTabCtrl, CTabViewTabItem>
{
	typedef CDotNetTabCtrlImpl<CFlyingTabCtrl, CTabViewTabItem>	baseClass;
	typedef CFlyingTabCtrl										thisClass;
protected:
	class CTabMoveTracker : public CDDTrackerBaseT<CTabMoveTracker>
	{
		typedef thisClass CTabCtrl;
	public:
		CTabMoveTracker(CTabCtrl& ctrlTab,int index)
			:m_ctrlTab(ctrlTab),m_curItem(index),m_prevItem(-1)
		{
			DWORD style = ctrlTab.GetWindowLong(GWL_STYLE);
			m_bHorizontal=(style&CTCS_VERTICAL)==0;
		}
		bool IsHorisontal() const
		{
			return m_bHorizontal;
		}
		void OnMove(long x, long y)
		{
			int pos = IsHorisontal() ? x : y;
			CTCHITTESTINFO tchti = { 0 };
			tchti.pt.x = x;
			tchti.pt.y = y;
			int index=m_ctrlTab.HitTest(&tchti);
			if(index!=-1)
			{
				if(( index!=m_curItem)
					&&
					 !( ( index==m_prevItem)
						&& ( (pos-m_prevPos)*(m_prevItem-m_curItem) <=0) ) )
				{
					m_ctrlTab.SwapItemPositions(m_curItem,index, false, false);
//					m_ctrlTab.MoveItem(m_curItem,index);
					m_curItem=index;
					m_ctrlTab.SetCurSel(m_curItem);
					m_prevItem=m_ctrlTab.HitTest(&tchti);
				}
			}
			else
				::ReleaseCapture();
/*
			{
				NMHDR nmh;
				nmh.hwndFrom = m_ctrlTab.m_hWnd;
				nmh.idFrom=m_ctrlTab.GetDlgCtrlID();
				nmh.code=CTCN_TABLEAVCTRL;
				if(!::SendMessage(m_ctrlTab.GetParent(), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh))
																				::ReleaseCapture();
			}
*/
			m_prevPos = pos;
		}
	protected:
		CTabCtrl&	m_ctrlTab;
		int			m_curItem;
		int			m_prevItem;
		int			m_prevPos;
		bool		m_bHorizontal;
	};
protected:
    void UpdateTabAreaHeight()
    {
        // Take into consideration system metrics when determining
        //  the height of the tab area
        const int nNominalHeight = 24;
        const int nNominalFontLogicalUnits = 11;        // 8 point Tahoma with 96 DPI

        // Use the actual font of the tab control
        assert(IsWindow());
        HFONT hFont = GetFont();
        if(hFont != NULL)
        {
            CDC dc = GetDC();
            CFontHandle hFontOld = dc.SelectFont(hFont);
            TEXTMETRIC tm = {0};
            dc.GetTextMetrics(&tm);
            dc.SelectFont(hFontOld);
			m_tabBarHeight = (BYTE)(nNominalHeight + (nNominalHeight * ((double)tm.tmAscent / (double)nNominalFontLogicalUnits) - nNominalHeight) / 2);
        }
		else
			m_tabBarHeight = 24;
    }
	void AdjustTabRect(LPRECT pRc) const
	{
		int tabHeight = m_tabBarHeight ;
		DWORD style = GetWindowLong(GWL_STYLE);
		if(style&CTCS_VERTICAL)
		{
			if(style&CTCS_BOTTOM)
				pRc->left=pRc->right - tabHeight;
			else
				pRc->right=pRc->left + tabHeight;
		}
		else
		{
			if(style&CTCS_BOTTOM)
				pRc->top=pRc->bottom - tabHeight;
			else
				pRc->bottom=pRc->top + tabHeight;
		}
	}
public:
	bool GetTabsRect(LPRECT pRc) const
	{
		return (GetClientRect(pRc)!=FALSE);
	}
/*
    int InsertItem(int nItem, LPCTSTR sText = NULL, int nImage = -1, HWND hWndTabView = NULL, LPCTSTR sToolTip = NULL, bool bSelectItem = false)
    {
		return baseClass::InsertItem(nItem, sText, nImage, hWndTabView, sToolTip, bSelectItem);
	}
	int InsertItem(int nItem, CTabViewTabItem* pItem, bool bSelectItem = false)
	{
		return baseClass::InsertItem(nItem, pItem, bSelectItem);
	}
*/
	int InsertItem(int index, LPCTSTR ptxt = NULL, int image = -1, DWORD param=0)
	{
		CTabViewTabItem* pItem = baseClass::CreateNewItem();
		if(pItem)
		{
			pItem->SetText(ptxt);
			pItem->SetImageIndex(image);
			pItem->SetTabView(reinterpret_cast<HWND>(param));
			pItem->SetToolTip(ptxt);

			return baseClass::InsertItem(index,pItem,true);
		}
		return -1;
	}
	DWORD GetItemData(int index) const
	{
		return reinterpret_cast<DWORD>(GetItem(index)->GetTabView());
	}

	void DeleteItem(CTabViewTabItem* pItem)
	{
		baseClass::DeleteItem(pItem);
	}
	BOOL DeleteItem(size_t nItem, bool bUpdateSelection = true, bool bNotify = true)
	{
		return baseClass::DeleteItem(nItem, bUpdateSelection, bNotify);
	}

	BOOL DeleteItem(int index,bool bUpdateSelection = true)
	{
		return DeleteItem(index, bUpdateSelection , false);
	}
    BOOL SetWindowPos(HWND hWndInsertAfter, LPCRECT lpRect, UINT nFlags)
    {
		CRect rc(lpRect);
		AdjustTabRect(rc);
		BOOL bRes=baseClass::SetWindowPos(hWndInsertAfter,&rc,nFlags);
		return bRes;
	}

	BOOL AdjustRect( BOOL bLarger, LPRECT pRc) const
	{
		int tabHeight = bLarger ? -m_tabBarHeight : m_tabBarHeight ;
		DWORD style = GetWindowLong(GWL_STYLE);
		if(style&CTCS_VERTICAL)
		{
			if(style&CTCS_BOTTOM)
				pRc->right-=tabHeight;
			else
				pRc->left+=tabHeight;
		}
		else
		{
			if(style&CTCS_BOTTOM)
				pRc->bottom-=tabHeight;
			else
				pRc->top+=tabHeight;

		}
		return TRUE;
	}

	DECLARE_WND_CLASS(_T("CFlyingTabCtrl"))
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		UpdateTabAreaHeight();
		bHandled=FALSE;
		return NULL;
	}

	LRESULT OnSetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		UpdateTabAreaHeight();
		bHandled=FALSE;
		return NULL;
	}

	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LRESULT lRes=baseClass::OnLButtonDown(uMsg,wParam,lParam,bHandled);
		bHandled=TRUE;
		CTCHITTESTINFO tchti = { 0 };
		tchti.pt.x = GET_X_LPARAM(lParam);
		tchti.pt.y = GET_Y_LPARAM(lParam);
		int index=HitTest(&tchti);
		if(index!=-1)
		{
			ClientToScreen(&tchti.pt);
			if(DragDetect(m_hWnd,tchti.pt))
			{
				CTabMoveTracker tracker(*this,index);
				if(TrackDragAndDrop(tracker,m_hWnd))
				{
					CTCHITTESTINFO tchti = { 0 };
					::GetCursorPos(&tchti.pt);
					ScreenToClient(&tchti.pt);
					int index=HitTest(&tchti);
					if(index==-1)
					{
						MSG msg;
						while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
							DispatchMessage(&msg);
						NMHDR nmh;
						nmh.hwndFrom = m_hWnd;
						nmh.idFrom=GetDlgCtrlID();
						nmh.code=CTCN_TABLEAVCTRL;
						::SendMessage(GetParent(), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh);
					}
				}
			}
		}
		return lRes;
	}

	LRESULT OnLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		CTCHITTESTINFO tchti = { 0 };
		tchti.pt.x = GET_X_LPARAM(lParam);
		tchti.pt.y = GET_Y_LPARAM(lParam);
		int index=HitTest(&tchti);
		if(index!=-1)
		{
			NMHDR nmh;
			nmh.hwndFrom = m_hWnd;
			nmh.idFrom=GetDlgCtrlID();
			nmh.code=NM_DBLCLK;
			::SendMessage(GetParent(), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh);
		}
		return 0;
	}
protected:
	int m_tabBarHeight;
};
}//namespace dockwins
#endif // __WTL_DW__FLYING_TABS_H__

⌨️ 快捷键说明

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