tabber.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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_SHOWNA );
  64. }
  65. Tabber::Tab *Tabber::getTab( int index )const{
  66. if( index<0 || index>=tabs.size() ) return 0;
  67. Tabs::const_iterator it=tabs.begin();
  68. while( index-- ) ++it;
  69. return *it;
  70. }
  71. void Tabber::tcn_selChange( NMHDR *p,LRESULT *result ){
  72. setCurrent( GetCurSel() );
  73. }
  74. void Tabber::insert( int index,CWnd *w,const string &t ){
  75. if( index<0 || index>tabs.size() ) return;
  76. Tabs::iterator it=tabs.begin();
  77. for( int k=0;k<index;++k ) ++it;
  78. Tab *tab=new Tab( w,t );
  79. tabs.insert( it,tab );
  80. InsertItem( index,t.c_str() );
  81. if( curr<0 ) setCurrent( index );
  82. }
  83. void Tabber::remove( int index ){
  84. if( index<0 || index>=tabs.size() ) return;
  85. CWnd *w=getTabWnd( index );
  86. Tabs::iterator it=tabs.begin();
  87. for( int k=0;k<index;++k ) ++it;
  88. delete *it;tabs.erase( it );
  89. DeleteItem( index );
  90. if( curr>=tabs.size() ) curr=tabs.size()-1;
  91. refresh();
  92. if( curr>=0 ) SetCurSel( curr );
  93. if( w ) w->ShowWindow( SW_HIDE );
  94. if( listener ) listener->currentSet( this,curr );
  95. }
  96. void Tabber::setCurrent( int index ){
  97. if( index<0 || index>=tabs.size() ) return;
  98. if( index!=curr ){
  99. CWnd *w=getTabWnd( curr );
  100. curr=index;
  101. refresh();
  102. SetCurSel( curr );
  103. if( w ) w->ShowWindow( SW_HIDE );
  104. }
  105. if( listener ) listener->currentSet( this,curr );
  106. }
  107. void Tabber::setTabText( int index,const string &t ){
  108. if( index<0 || index>=tabs.size() ) return;
  109. string s=t+'\0';
  110. TCITEM tc={ TCIF_TEXT };
  111. tc.pszText=(char*)s.data();
  112. SetItem( index,&tc );
  113. }
  114. int Tabber::size()const{
  115. return tabs.size();
  116. }
  117. int Tabber::getCurrent()const{
  118. return curr;
  119. }
  120. CWnd *Tabber::getTabWnd( int index )const{
  121. Tab *t=getTab( index );
  122. return t ? t->wnd : 0;
  123. }
  124. string Tabber::getTabText( int index )const{
  125. Tab *t=getTab( index );
  126. return t ? t->text : "";
  127. }