📄 docktabpane.h
字号:
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 + -