#include "stdafx.h" #include "tabber.h" IMPLEMENT_DYNAMIC( Tabber,CTabCtrl ) BEGIN_MESSAGE_MAP( Tabber,CTabCtrl ) ON_WM_SIZE() ON_WM_ERASEBKGND() ON_NOTIFY_REFLECT( TCN_SELCHANGE,tcn_selChange ) END_MESSAGE_MAP() static CRect tabsRect( CTabCtrl &t ){ CRect r(0,0,0,0); int n=t.GetItemCount(); for( int k=0;kr.right ) r.right=c.right; if( c.topr.bottom ) r.bottom=c.bottom; } return r; } CRect Tabber::getInnerRect(){ CRect r; GetClientRect( &r ); int x=2,y=2,w=r.Width()-4,h=r.Height()-4; r=tabsRect( *this ); h-=r.Height();y+=r.Height(); r.left=x;r.top=y;r.right=x+w;r.bottom=y+h; return r; } Tabber::Tabber(): listener(0),curr(-1){ } Tabber::~Tabber(){ for( ;tabs.size();tabs.pop_back() ) delete tabs.back(); } void Tabber::OnSize( UINT type,int w,int h ){ CTabCtrl::OnSize( type,w,h ); refresh(); } BOOL Tabber::OnEraseBkgnd( CDC *dc ){ CRect c;GetClientRect( &c ); HBRUSH hb=(HBRUSH)GetClassLong( m_hWnd,GCL_HBRBACKGROUND ); CBrush br;br.Attach( hb ); if( curr<0 ) dc->FillRect( &c,&br ); else{ CRect i=getInnerRect(); CRect t( c.left,c.top,i.right,i.top );dc->FillRect( &t,&br ); CRect r( i.right,c.top,c.right,i.bottom );dc->FillRect( &r,&br ); CRect b( i.left,i.bottom,c.right,c.bottom );dc->FillRect( &b,&br ); CRect l( c.left,i.top,i.left,c.bottom );dc->FillRect( &l,&br ); } return true; } void Tabber::setListener( TabberListener *l ){ listener=l; } void Tabber::refresh(){ if( curr<0 ) return; CRect r=getInnerRect(); CWnd *wnd=getTabWnd( curr ); wnd->MoveWindow( r.left,r.top,r.Width(),r.Height() ); wnd->ShowWindow( SW_SHOW ); wnd->SetFocus(); } Tabber::Tab *Tabber::getTab( int index )const{ if( index<0 || index>=tabs.size() ) return 0; Tabs::const_iterator it=tabs.begin(); while( index-- ) ++it; return *it; } void Tabber::tcn_selChange( NMHDR *p,LRESULT *result ){ setCurrent( GetCurSel() ); } void Tabber::insert( int index,CWnd *w,const string &t ){ if( index<0 || index>tabs.size() ) return; Tabs::iterator it=tabs.begin(); for( int k=0;k=tabs.size() ) return; CWnd *w=getTabWnd( index ); Tabs::iterator it=tabs.begin(); for( int k=0;k=tabs.size() ) curr=tabs.size()-1; refresh(); if( curr>=0 ) SetCurSel( curr ); if( w ) w->ShowWindow( SW_HIDE ); if( listener ) listener->currentSet( this,curr ); } void Tabber::setCurrent( int index ){ if( index<0 || index>=tabs.size() ) return; if( index!=curr ){ CWnd *w=getTabWnd( curr ); curr=index; refresh(); SetCurSel( curr ); if( w ) w->ShowWindow( SW_HIDE ); } if( listener ) listener->currentSet( this,curr ); } void Tabber::setTabText( int index,const string &t ){ if( index<0 || index>=tabs.size() ) return; string s=t+'\0'; TCITEM tc={ TCIF_TEXT }; tc.pszText=(char*)s.data(); SetItem( index,&tc ); } int Tabber::size()const{ return tabs.size(); } int Tabber::getCurrent()const{ return curr; } CWnd *Tabber::getTabWnd( int index )const{ Tab *t=getTab( index ); return t ? t->wnd : 0; } string Tabber::getTabText( int index )const{ Tab *t=getTab( index ); return t ? t->text : ""; }