tabber.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "stdafx.h"
  2. #include "tabber.h"
  3. IMPLEMENT_DYNAMIC( Tabber,CTabCtrl )
  4. BEGIN_MESSAGE_MAP( Tabber,CTabCtrl )
  5. ON_WM_SIZE()
  6. ON_WM_ERASEBKGND()
  7. ON_NOTIFY_REFLECT( TCN_SELCHANGE,tcn_selChange )
  8. END_MESSAGE_MAP()
  9. static CRect tabsRect( CTabCtrl &t ){
  10. CRect r(0,0,0,0);
  11. int n=t.GetItemCount();
  12. for( int k=0;k<n;++k ){
  13. CRect c;
  14. t.GetItemRect( k,&c );
  15. if( c.left<r.left ) r.left=c.left;
  16. if( c.right>r.right ) r.right=c.right;
  17. if( c.top<r.top ) r.top=c.top;
  18. if( c.bottom>r.bottom ) r.bottom=c.bottom;
  19. }
  20. return r;
  21. }
  22. CRect Tabber::getInnerRect(){
  23. CRect r;
  24. GetClientRect( &r );
  25. int x=2,y=2,w=r.Width()-4,h=r.Height()-4;
  26. r=tabsRect( *this );
  27. h-=r.Height();y+=r.Height();
  28. r.left=x;r.top=y;r.right=x+w;r.bottom=y+h;
  29. return r;
  30. }
  31. Tabber::Tabber():
  32. listener(0),curr(-1){
  33. }
  34. Tabber::~Tabber(){
  35. for( ;tabs.size();tabs.pop_back() ) delete tabs.back();
  36. }
  37. void Tabber::OnSize( UINT type,int w,int h ){
  38. CTabCtrl::OnSize( type,w,h );
  39. refresh();
  40. }
  41. BOOL Tabber::OnEraseBkgnd( CDC *dc ){
  42. CRect c;GetClientRect( &c );
  43. HBRUSH hb=(HBRUSH)GetClassLong( m_hWnd,GCL_HBRBACKGROUND );
  44. CBrush br;br.Attach( hb );
  45. if( curr<0 ) dc->FillRect( &c,&br );
  46. else{
  47. CRect i=getInnerRect();
  48. CRect t( c.left,c.top,i.right,i.top );dc->FillRect( &t,&br );
  49. CRect r( i.right,c.top,c.right,i.bottom );dc->FillRect( &r,&br );
  50. CRect b( i.left,i.bottom,c.right,c.bottom );dc->FillRect( &b,&br );
  51. CRect l( c.left,i.top,i.left,c.bottom );dc->FillRect( &l,&br );
  52. }
  53. return true;
  54. }
  55. void Tabber::setListener( TabberListener *l ){
  56. listener=l;
  57. }
  58. void Tabber::refresh(){
  59. if( curr<0 ) return;
  60. CRect r=getInnerRect();
  61. CWnd *wnd=getTabWnd( curr );
  62. wnd->MoveWindow( r.left,r.top,r.Width(),r.Height() );
  63. wnd->ShowWindow( SW_SHOW );
  64. wnd->SetFocus();
  65. }
  66. Tabber::Tab *Tabber::getTab( int index )const{
  67. if( index<0 || index>=tabs.size() ) return 0;
  68. Tabs::const_iterator it=tabs.begin();
  69. while( index-- ) ++it;
  70. return *it;
  71. }
  72. void Tabber::tcn_selChange( NMHDR *p,LRESULT *result ){
  73. setCurrent( GetCurSel() );
  74. }
  75. void Tabber::insert( int index,CWnd *w,const string &t ){
  76. if( index<0 || index>tabs.size() ) return;
  77. Tabs::iterator it=tabs.begin();
  78. for( int k=0;k<index;++k ) ++it;
  79. Tab *tab=new Tab( w,t );
  80. tabs.insert( it,tab );
  81. InsertItem( index,t.c_str() );
  82. if( curr<0 ) setCurrent( index );
  83. }
  84. void Tabber::remove( int index ){
  85. if( index<0 || index>=tabs.size() ) return;
  86. CWnd *w=getTabWnd( index );
  87. Tabs::iterator it=tabs.begin();
  88. for( int k=0;k<index;++k ) ++it;
  89. delete *it;tabs.erase( it );
  90. DeleteItem( index );
  91. if( curr>=tabs.size() ) curr=tabs.size()-1;
  92. refresh();
  93. if( curr>=0 ) SetCurSel( curr );
  94. if( w ) w->ShowWindow( SW_HIDE );
  95. if( listener ) listener->currentSet( this,curr );
  96. }
  97. void Tabber::setCurrent( int index ){
  98. if( index<0 || index>=tabs.size() ) return;
  99. if( index!=curr ){
  100. CWnd *w=getTabWnd( curr );
  101. curr=index;
  102. refresh();
  103. SetCurSel( curr );
  104. if( w ) w->ShowWindow( SW_HIDE );
  105. }
  106. if( listener ) listener->currentSet( this,curr );
  107. }
  108. void Tabber::setTabText( int index,const string &t ){
  109. if( index<0 || index>=tabs.size() ) return;
  110. string s=t+'\0';
  111. TCITEM tc={ TCIF_TEXT };
  112. tc.pszText=(char*)s.data();
  113. SetItem( index,&tc );
  114. }
  115. int Tabber::size()const{
  116. return tabs.size();
  117. }
  118. int Tabber::getCurrent()const{
  119. return curr;
  120. }
  121. CWnd *Tabber::getTabWnd( int index )const{
  122. Tab *t=getTab( index );
  123. return t ? t->wnd : 0;
  124. }
  125. string Tabber::getTabText( int index )const{
  126. Tab *t=getTab( index );
  127. return t ? t->text : "";
  128. }