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

📄 docktabpane.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 2 页
字号:
		int getTabIndex( HWND win) const {
			
			return this->tabs.getIndex( win);
		}
		
		bool deleteTab( int index) {
			
			ATLASSERT( 0 <= index && index < this->tabs.GetItemCount());
			
			return this->tabs.DeleteItem( index) == TRUE;
		}
		
		HWND getTabWND( int index) const {
			
			ATLASSERT( 0 <= index && index < this->tabs.GetItemCount());
			
			return this->tabs.getWND( index);
		}
		
	//----------------- public interface
	public:
		
		// Constructor/destructor
		Pane( CallBackListener* listener, bool isTabsOnTop = true)
			: tabs( this)
			, cbListener( listener)
			, isTabsOnTop( isTabsOnTop)
		{
			ATLASSERT( listener);
		}
		
		~Pane() {
			
			if ( this->m_hWnd) {
				
				this->DestroyWindow();
				this->m_hWnd = NULL;
			}
		}
		
		// public interface
		void showCurrent() {
			
			int clientCount = this->clientCount();
			if ( clientCount > 0) {
				
				CRect tabPageRect;
				this->getTabPageRect( tabPageRect);
				::SetWindowPos( this->getTabWND( this->getCurrentTab())
				              , HWND_TOP
				              , tabPageRect.left
				              , tabPageRect.top
				              , tabPageRect.Width()
				              , tabPageRect.Height()
				              , SWP_SHOWWINDOW
				              );
			} else
				this->tabs.SetWindowPos( HWND_BOTTOM, 0,0,0,0, SWP_HIDEWINDOW);
		}
		
		void getTabRect( LPRECT tabRect) {
			
			ATLASSERT( NULL != tabRect);
			
			int tabHeight;
			if ( this->tabs.GetItemCount() > 0) {
				
				tabHeight = this->tabs.getHeight();
			} else
				tabHeight = 0;
			
			this->GetClientRect( tabRect);
			if ( this->isTabsOnTop)
				tabRect->bottom = tabHeight;
			else
				tabRect->top = tabRect->bottom - tabHeight;
		}
		
		void getTabPageRect( LPRECT tabPageRect) {
			
			ATLASSERT( NULL != tabPageRect);
			
			int tabHeight;
			if ( this->tabs.GetItemCount() > 0) {
				
				tabHeight = this->tabs.getHeight();
			} else
				tabHeight = 0;
			this->GetClientRect( tabPageRect);
			if ( this->isTabsOnTop)
				tabPageRect->top += tabHeight;
			else
				tabPageRect->bottom = tabPageRect->bottom - tabHeight;
		}
		
		bool isEmpty() {
			
			return this->clientCount() == 0;
		}
		
		int clientCount() {
			
			return this->tabs.GetItemCount();
		}
		
		bool setFocusTo( HWND clientViewWnd) {
			
			int index = this->getTabIndex( clientViewWnd);
			if ( -1 < index) {
				
				this->setCurrentTab( index);
				CRect clientRect;
				this->getTabPageRect( clientRect);
				CWindow win( clientViewWnd);
				win.SetWindowPos( HWND_TOP, clientRect, SWP_SHOWWINDOW);
				return true;
			}

			return false;
		}
		
		bool removeClientView( HWND childWnd) {
			
			int currentTab = this->getCurrentTab();
			int tabIndex   = this->getTabIndex( childWnd);
			
			if ( tabIndex == currentTab && this->clientCount() > 1)
				this->setCurrentTab( ( tabIndex == 0)? 1: tabIndex-1);
			
			bool result = this->tabs.removeTab( tabIndex);
			
			this->showCurrent();
			
			return result;
		};
		
		HWND moveCurrentTabTo( Pane* targetPane) {
			
			ATLASSERT( NULL != targetPane);
			
			int currentTab = this->getCurrentTab();
			
			TabControlItem* item = this->tabs.GetItem( currentTab);
			HWND result = item->clientViewWnd;
			int insertedTab = targetPane->clientCount();
			targetPane->insertTab( insertedTab
			                     , item->GetText()
			                     , item->clientViewWnd
			                     , item->GetToolTip()
			                     , item->GetImageIndex()
			                     );
			
			targetPane->setCurrentTab( insertedTab);
			this->tabs.DeleteItem( currentTab);
			this->showCurrent();
			
			return result;
		}
		
		void updateLayout() {
			
			if ( this->tabs.GetItemCount() > 0) {
				
				CRect rect;
				this->GetClientRect( &rect);
				WORD width  = rect.Width();
				WORD height = rect.Height();
				
				this->tabs.GetItemRect( 0, &rect);
				int tabHeight = this->tabs.getHeight();
				
				this->tabs.SetWindowPos( HWND_TOP
				                       , 0
				                       , ( this->isTabsOnTop)? 0: height - tabHeight
				                       , width
				                       , tabHeight
				                       , SWP_SHOWWINDOW
				                       );
				
				int currentTabIndex = this->getCurrentTab();
				if ( currentTabIndex > -1) {
					
					HWND hWnd = this->getTabWND( currentTabIndex);
					::SetWindowPos( hWnd
					              , HWND_TOP
					              , 0
								  , ( this->isTabsOnTop)? tabHeight: 0
					              , width
					              , height - tabHeight
					              , SWP_SHOWWINDOW
					              );
				}
			} else
				this->tabs.SetWindowPos( HWND_TOP, &rcDefault, SWP_SHOWWINDOW);
		}

		void redrawTabControl()
		{
			this->tabs.UpdateLayout();
		}

		bool append( const TCHAR* caption, HWND hWnd, const TCHAR* toolTip = NULL, int imageIndex = -1) {
			
			int lastTabIndex = this->clientCount();
			
			this->insertTab( lastTabIndex, caption, hWnd, toolTip, imageIndex);
			return true;
		}
		
		bool get( HWND clientViewWnd, ClientProperties& clientProperties) {
			
			for ( int i=0; i<this->clientCount(); i++) {
				
				TabControlItem* item = this->tabs.GetItem( i);
				if ( clientViewWnd == item->clientViewWnd) {
					clientProperties.caption    = item->GetText();
					clientProperties.imageIndex = item->GetImageIndex();
					clientProperties.toolTip    = item->GetToolTip();
					return true;
				}
			}
			
			return false;
		}

		TabControlItem* get(HWND clientViewWnd)
		{
			for ( int i=0; i<this->clientCount(); i++) {

				TabControlItem* item = this->tabs.GetItem( i);
				if ( clientViewWnd == item->clientViewWnd) {
					return item;
				}
			}
			return NULL;
		}
		
		HWND focusedClientView() const {
			
			int index = this->getCurrentTab();
			return index > -1? this->tabs.getWND( index): NULL;
		}
		
		void setImageList( HIMAGELIST imageList) {
			
			::SendMessage( this->tabs.m_hWnd, TCM_SETIMAGELIST, 0, (LPARAM)imageList);
		}
		
		enum TabPaneHitTest {
			  TabPaneHitTest_Unknown = 0
			, TabPaneHitTest_TabArea = 1
			, TabPaneHitTest_Top     = 2
			, TabPaneHitTest_Right   = 3
			, TabPaneHitTest_Left    = 4
			, TabPaneHitTest_Bottom  = 5
		};
		
		TabPaneHitTest hitTest( LPPOINT point) {
			
			ATLASSERT( NULL != point);
			
			CPoint hitPoint( *point);
			this->ScreenToClient( &hitPoint);
			CRect rect;
			this->getTabRect( &rect);
			if ( rect.PtInRect( hitPoint))
				return TabPaneHitTest_TabArea;
			
			this->getTabPageRect( &rect);
			if ( !rect.PtInRect( hitPoint))
				return TabPaneHitTest_Unknown;
			
			TabPaneHitTest result = TabPaneHitTest_Unknown;
			long dsize  = 0;
			long top    = hitPoint.y - rect.top;
			long bottom = rect.bottom - hitPoint.y;
			if ( top < bottom) {
				result = TabPaneHitTest_Top;
				dsize  = top;
			} else {
				result = TabPaneHitTest_Bottom;
				dsize  = bottom;
			}
			long left  = hitPoint.x - rect.left;
			if ( left < dsize) {
				result = TabPaneHitTest_Left;
				dsize = left;
			}
			long right = rect.right - hitPoint.x;
			if ( right < dsize)
				result = TabPaneHitTest_Right;
			
			return result;
		}
		
		// CallBackListener inteface
		void clientActivate(  HWND childWnd, HWND clientViewWnd) {
			
			this->cbListener->clientActivate( this->m_hWnd, clientViewWnd);
			return;
		}
		
		void clientDblClick(  HWND childWnd, HWND clientViewWnd) {
			
			this->cbListener->clientDblClick( this->m_hWnd, clientViewWnd);
			return;
		}
		
		void clientCloseClick(  HWND childWnd, HWND clientViewWnd) {
			
			this->cbListener->clientCloseClick( this->m_hWnd, clientViewWnd);
			return;
		}
		
		void dragStart( HWND client, HWND clientViewWnd, long x, long y, DWORD keysPressed) {
			
			this->cbListener->dragStart( this->m_hWnd, clientViewWnd, x, y, keysPressed);
			return;
		}
		
		void dragOver( HWND client, HWND clientViewWnd, long x, long y, DWORD keysPressed) {
			
			this->cbListener->dragOver( this->m_hWnd, clientViewWnd, x, y, keysPressed);
			return;
		}
		
		void dragDrop( HWND client, HWND clientViewWnd, long x, long y, DWORD keysPressed) {
			
			this->cbListener->dragDrop( this->m_hWnd, clientViewWnd, x, y, keysPressed);
			return;
		}
		
		void dragCancel( HWND client, HWND clientViewWnd) {
			
			this->cbListener->dragCancel( this->m_hWnd, clientViewWnd);
			return;
		}
		
		// Overrideables
		BOOL DestroyWindow() throw() {
		
			ATLASSERT(::IsWindow(m_hWnd));
			
			::DestroyWindow( this->tabs.m_hWnd);
			::DestroyWindow( m_hWnd);
			this->tabs.m_hWnd = NULL;
			m_hWnd = NULL;
			return TRUE;
		}
		
		// Message Map
		DECLARE_WND_CLASS(_T("DockTab::Pane"))
		
		BEGIN_MSG_MAP(thisClass)
			MESSAGE_HANDLER( WM_CREATE,        OnCreate)
			MESSAGE_HANDLER( WM_ERASEBKGND,    OnEraseBackground)
			MESSAGE_HANDLER( WM_SETFOCUS,      OnSetFocus)
			MESSAGE_HANDLER( WM_SIZE,          OnSize)
			MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate)
			
			NOTIFY_HANDLER( 0, CTCN_CLOSE,       OnTabClose);
			NOTIFY_HANDLER( 0, CTCN_SELCHANGING, OnTabSelChanging);
			NOTIFY_HANDLER( 0, CTCN_SELCHANGE,   OnTabSelChange);
			NOTIFY_HANDLER( 0, NM_DBLCLK,        OnTabDoubleClick);
		END_MSG_MAP()
		
		LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
			
			LRESULT result = this->DefWindowProc( uMsg, wParam, lParam);
			if ( MA_ACTIVATE == result || MA_ACTIVATEANDEAT == result)
				this->SetFocus();
			return result;
		}
		
		LRESULT OnTabClose( int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) {
			
			LPNMCTCITEM notifyItem = reinterpret_cast<LPNMCTCITEM>(pnmh);
			if ( notifyItem->iItem > -1 && NULL != this->cbListener)
				this->cbListener->clientCloseClick( this->m_hWnd, this->tabs.getWND( notifyItem->iItem));
			return TRUE;
		}
		
		LRESULT OnTabDoubleClick( int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) {
			
			LPNMCTCITEM notifyItem = reinterpret_cast<LPNMCTCITEM>(pnmh);
			if ( notifyItem->iItem > -1 && NULL != this->cbListener)
				this->cbListener->clientDblClick( this->m_hWnd, this->tabs.getWND( notifyItem->iItem));
			return TRUE;
		}
		
		LRESULT OnSetFocus( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
			
			int currentIndex = this->tabs.GetCurSel();
			if ( currentIndex > -1) {
				
				TabControlItem* item = this->tabs.GetItem( currentIndex);
				if ( NULL != ::SetFocus( item->clientViewWnd) && NULL != this->cbListener)
					this->cbListener->clientActivate( this->m_hWnd, item->clientViewWnd);
			} else if ( NULL != this->cbListener)
				this->cbListener->clientActivate( this->m_hWnd, NULL);
			return 0;
		}
		
		LRESULT OnTabSelChanging( int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) {
			
			LPNMCTC2ITEMS nmct = reinterpret_cast< LPNMCTC2ITEMS>( pnmh);
			
			if ( nmct->iItem1 > -1)
				::SetWindowPos( getTabWND( nmct->iItem1), NULL, 0, 0, 0, 0
				              , SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
				              );
			return FALSE;
		}
		
		LRESULT OnTabSelChange( int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) {
			
			CRect rect;
			this->getTabPageRect( &rect);
			
			HWND clientViewWnd = this->getTabWND( this->getCurrentTab());
			::SetWindowPos( clientViewWnd, HWND_TOP, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW);
			
			if ( NULL != ::SetFocus( clientViewWnd) && NULL != this->cbListener)
				this->cbListener->clientActivate( this->m_hWnd, clientViewWnd);
			
			return TRUE;
		}
		
		LRESULT OnCreate( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
			
			this->tabs.create( this->m_hWnd, this->isTabsOnTop);
			return 0;
		}
		
		LRESULT OnSize( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
			
			if ( this->tabs.GetItemCount() > 0) {
				
				WORD width  = LOWORD( lParam);
				WORD height = HIWORD( lParam);
				
				int tabHeight = this->tabs.getHeight();
				
				this->tabs.SetWindowPos( NULL
				                       , 0
				                       , ( this->isTabsOnTop)? 0: height - tabHeight
				                       , width
				                       , tabHeight
				                       , SWP_NOZORDER
				                       );
				
				int currentTabIndex = this->getCurrentTab();
				if ( currentTabIndex > -1) {
					
					HWND hWnd = this->getTabWND( currentTabIndex);
					::SetWindowPos( hWnd
					              , HWND_TOP
					              , 0
								  , ( this->isTabsOnTop)? tabHeight: 0
					              , width
					              , height - tabHeight
					              , SWP_SHOWWINDOW
					              );
				}
			} else
				this->tabs.SetWindowPos( HWND_TOP, &rcDefault, SWP_SHOWWINDOW);
			return 0;
		}
		
		LRESULT OnEraseBackground( UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
			
			WTL::CDCHandle cdc = ( HDC) wParam;
			if ( this->tabs.GetItemCount() == 0) {
				
				CRect rect;
				this->GetClientRect( &rect);
				cdc.FillRect( rect, (HBRUSH) GetStockObject( DKGRAY_BRUSH));
			}
			return TRUE;
		}
		
	}; // class Pane
		
}; // namespace DockSplitTab

#endif // __DOCKTAB_PANE_H__

⌨️ 快捷键说明

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