www.pudn.com > clking_src.rar > GuiTabWnd.cpp


//-----------------------------------------------------------------------// 
// This is a part of the GuiLib MFC Extention.							 //	 
// Autor  :  Francisco Campos											 // 
// (C) 2002 Francisco Campos  All rights reserved     // 
// This code is provided "as is", with absolutely no warranty expressed  // 
// or implied. Any use is at your own risk.								 //		 
// You must obtain the author's consent before you can include this code // 
// in a software library.												 // 
// If the source code in  this file is used in any application			 // 
// then acknowledgement must be made to the author of this program		 //	 
// fcampos@tutopia.com													 // 
//-----------------------------------------------------------------------// 
 
 
 
#include "stdafx.h" 
 
#include "GuiTabWnd.h" 
#include "GuiBasetab.h" 
#include "resource.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CGuiTabWnd 
 
#define  SPACE_TAB		4 
#define  DEFAULT_FLAT	18 
 
CGuiTabWnd::CGuiTabWnd() 
{ 
	m_rectCliente.SetRectEmpty(); 
	m_rectTab.SetRectEmpty(); 
	m_ActualVar=0; 
	m_Numtabs=0; 
	m_iSelectTab=0; 
	m_sizeImag=CSize(15,15); 
	m_pArray.RemoveAll(); 
	m_iMinValRec=0;  //minimo valor requerido para mostrar toda las carpetas 
	 
	// Modified Bu SunZhenyu 
	if( !m_cfont.CreateStockObject( DEFAULT_GUI_FONT ) ) 
		m_cfont.CreateStockObject( ANSI_VAR_FONT ); 
	// m_cfont.CreateFont(-11,0,0,0,400,0,0,0,0,1,2,1,34,"MS Sans Serif"); 
	m_style=S3D; 
	m_ActualTitle=TRUE; 
	m_alnTab=ALN_BOTTOM; 
	m_TypeTab=TYPE_NORMAL; 
 
	/*Modified By SunZhenyu 2003/11/11, add the next 2 line */ 
	m_clrSelectTabBK	=	::GetSysColor(COLOR_BTNHIGHLIGHT); 
	m_clrSelectTabText	=	::GetSysColor(COLOR_BTNTEXT); 
} 
 
CGuiTabWnd::~CGuiTabWnd() 
{ 
	/* Modified By SunZhenyu 2003/8/22, Add next 7 lines. */ 
	for(int i=0; imessage == WM_MOUSEMOVE) 
		CToolTip.RelayEvent(pMsg); 
 
	return CWnd::PreTranslateMessage(pMsg); 
} 
 
//**************************************************************************** 
void CGuiTabWnd::OnSysColorChange( ) 
{ 
	CWnd::OnSysColorChange( ); 
	 
} 
 
void CGuiTabWnd::SetTypeTab(TypeTab Type) 
{ 
	m_TypeTab=Type; 
} 
//**************************************************************************** 
BOOL CGuiTabWnd::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if (m_Numtabs == 0) 
	{ 
		CBrush cbr; 
		cbr.CreateSysColorBrush(COLOR_BTNFACE); 
		CRect m_rect; 
		GetClientRect(m_rect); 
		pDC->FillRect(m_rect,&cbr); 
		 
	} 
	return TRUE; 
} 
 
void CGuiTabWnd::SetActualTitle(BOOL bActual) 
{ 
	m_ActualTitle=bActual; 
} 
 
void CGuiTabWnd::SetALingTabs(AlingTab alnTab) 
{ 
	m_alnTab=alnTab; 
	Invalidate(); 
	UpdateWindow(); 
} 
 
void CGuiTabWnd::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	CBrush cbr; 
	CRect m_rectDraw; 
	if (m_alnTab!=ALN_TOP) 
		cbr.CreateSolidBrush(GuiDrawLayer::GetRGBColorXP()); 
	else 
		cbr.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace()); 
	GetClientRect(m_rectCliente); 
	m_rectTab=m_rectCliente; 
	m_rectDraw=m_rectCliente; 
	if (m_alnTab==ALN_BOTTOM) 
		m_rectDraw.bottom=m_rectCliente.bottom-(m_sizeImag.cy+SPACE_TAB+2);	 
	else 
		m_rectDraw.top=m_rectCliente.top+(m_sizeImag.cy+SPACE_TAB+2); 
	 
	if (m_alnTab!=ALN_TOP) 
	{ 
		/* Modified By SunZhenyu 2003/10/26, Remove next 2 lines. */ 
		// dc.FillRect(m_rectTab,&cbr); 
		// dc.Draw3dRect(m_rectDraw,GetSysColor(COLOR_BTNSHADOW),GetSysColor(COLOR_BTNSHADOW)); 
	} 
	else 
	{ 
		CRect rc=m_rectDraw; 
		for (int i=0; i< 2; i++) 
		{ 
			dc.Draw3dRect(rc,GuiDrawLayer::GetRGBColorFace(),GuiDrawLayer::GetRGBColorFace()); 
			rc.DeflateRect(1,1); 
		} 
		 
		rc.InflateRect(3,3); 
		dc.Draw3dRect(rc,GetSysColor(COLOR_BTNSHADOW),GetSysColor(COLOR_BTNSHADOW)); 
		rc=m_rectDraw; 
		rc.bottom=rc.top+3; 
		dc.FillRect(rc,&cbr); 
		 
	} 
	 
	 
	if (m_style != S3D) //si son carpetas estilo excel o tabbed como devstudio 7 
	{ 
		if (m_alnTab==ALN_BOTTOM) 
		{ 
			m_rectCliente.bottom=m_rectCliente.bottom-(DEFAULT_FLAT); 
			m_rectTab.top=m_rectCliente.bottom+2; 
		} 
		else 
		{ 
			m_rectTab.bottom=m_rectCliente.top+(DEFAULT_FLAT)+3; 
		} 
	} 
 
	Drawtabs(&dc); 
	 
} 
 
 
 
BOOL CGuiTabWnd::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	pParent= pParentWnd; 
	return CWnd::Create(NULL, _T(""), dwStyle, rect, pParentWnd, nID); 
} 
 
int CGuiTabWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	CToolTip.Create(this,TTS_ALWAYSTIP); 
	CToolTip.Activate(TRUE); 
	CToolTip.BringWindowToTop(); 
	// TODO: Add your specialized creation code here 
	 
	return 0; 
} 
 
 
void CGuiTabWnd::RecalLayout() 
{ 
	GetClientRect(m_rectCliente); 
 
	if (m_style == S3D) 
	{ 
		m_rectCliente.bottom=m_rectCliente.bottom-(m_sizeImag.cy+SPACE_TAB+1); 
	} 
	else 
	{ 
		if (m_alnTab==ALN_BOTTOM) 
			m_rectCliente.bottom=m_rectCliente.bottom-(DEFAULT_FLAT); 
		else 
		{ 
			m_rectCliente.top+=DEFAULT_FLAT; 
			m_rectCliente.bottom=m_rectCliente.bottom-(DEFAULT_FLAT+4); 
 
		} 
	} 
 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		CWnd* m_tempWin= ct->pParent; 
		ASSERT_VALID(m_tempWin); 
		if (m_style == S3D) 
		{ 
			   m_tempWin->SetWindowPos(NULL,m_rectCliente.left+(SPACE_TAB-2), 
			   m_rectCliente.top+(SPACE_TAB/2),m_rectCliente.right-(SPACE_TAB+1), 
			   m_rectCliente.bottom-(SPACE_TAB+2),SWP_NOACTIVATE| 
			   SWP_NOZORDER); 
		} 
		else 
		{ 
			if (m_alnTab==ALN_BOTTOM)	 
			{ 
			   m_tempWin->SetWindowPos(NULL,m_rectCliente.left+(SPACE_TAB-3), 
			   m_rectCliente.top+3,m_rectCliente.right-2, 
			   m_rectCliente.bottom-1,SWP_NOACTIVATE|SWP_NOZORDER); 
			} 
			else 
			{  
				if (m_TypeTab == TYPE_NORMAL) 
				{ 
				  m_tempWin->SetWindowPos(NULL,m_rectCliente.left+(SPACE_TAB-3), 
				  m_rectCliente.top+3,m_rectCliente.right-2, 
				  m_rectCliente.bottom,SWP_NOACTIVATE|SWP_NOZORDER); 
				} 
			} 
		} 
	} 
	AjustTabs(); 
	Invalidate(); 
	UpdateWindow(); 
} 
 
 
void CGuiTabWnd::AjustTabs() 
{ 
	int m_iSizeAct=0; 
	m_iMinValRec=4; 
	CClientDC dc(this); 
	GetClientRect(m_rectCliente); 
	if (m_alnTab==ALN_BOTTOM) 
		m_rectCliente.bottom=m_rectCliente.bottom-(m_sizeImag.cy+SPACE_TAB+1); 
	else 
		m_rectCliente.bottom=m_rectCliente.top+(m_sizeImag.cy+SPACE_TAB+1); 
 
	CFont* m_fontOld=dc.SelectObject(&m_cfont); 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		CRect m_Arect; 
		CSize m_sChar=dc.GetTextExtent(ct->lpMsg); 
		m_Arect.left=m_iMinValRec+1; 
		m_iMinValRec+=m_alnTab!=ALN_TOP?m_sizeImag.cx+2+m_sChar.cx+14:m_sChar.cx+14; 
		if(m_alnTab==ALN_BOTTOM) 
		{ 
			m_Arect.top=m_rectCliente.bottom; 
			m_Arect.right=m_iMinValRec; 
			m_Arect.bottom=m_rectCliente.bottom+4+m_sizeImag.cy; 
		} 
		else 
		{ 
			m_Arect.top=m_rectCliente.top; 
			m_Arect.right=m_iMinValRec; 
			m_Arect.bottom=m_rectCliente.top+4+m_sizeImag.cy; 
		} 
		ct->rect= m_Arect; 
		 
	}		 
	dc.SelectObject(m_fontOld); 
	//si el espacio requerido es mayor que el disponible 
	//se debe proporcionar cada tab solo si es 3d 
	if (m_style== S3D) 
	{ 
		int m_NewResize=4; 
		if (m_iMinValRec > m_rectCliente.Width()-4) 
		{ 
			m_iSizeAct=(m_rectCliente.Width()-12)/m_Numtabs; 
			for (int iCont=0; iCont< m_Numtabs;iCont++) 
			{ 
				CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
				CRect m_Arect; 
				m_Arect.left=m_NewResize; 
				m_Arect.right=m_NewResize+m_iSizeAct; 
				m_Arect.top=m_rectCliente.bottom; 
				m_Arect.bottom=m_rectCliente.bottom+4+m_sizeImag.cy; 
				m_NewResize+=m_iSizeAct+1; 
				ct->rect= m_Arect; 
			}	 
		} 
	} 
 
} 
void CGuiTabWnd::Drawtabs(CDC* dc) 
{ 
	CPen light(PS_SOLID,1,GetSysColor(COLOR_BTNHIGHLIGHT)); 
	CPen Dark(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW)); 
	CPen Black(PS_SOLID,1,GetSysColor(BLACK_PEN));	 
	CRect rectText; 
	CFont* m_fontOld=dc->SelectObject(&m_cfont); 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		CPen* oldPen= dc->SelectObject(&light); 
		//si es la carpeta seleccionada, se debe  
		//eliminar las lineas oscuras de encima 
		if (iCont ==m_iSelectTab) 
		{ 
			CBrush cbr; 
			CRect  m_rectTabAux=ct->rect; 
			m_rectTabAux.DeflateRect(1,1); 
			m_rectTabAux.top-=4;	 
			m_rectTabAux.bottom=m_rectTabAux.top+4; 
			cbr.CreateSysColorBrush(COLOR_BTNFACE); 
			 
			dc->FillRect(ct->rect,&cbr); 
			dc->MoveTo(ct->rect.left,ct->rect.top-3); 
			dc->LineTo(ct->rect.left,ct->rect.bottom-1); 
			dc->FillRect(m_rectTabAux,&cbr); 
 
			dc->SelectStockObject(BLACK_PEN); 
			dc->MoveTo(ct->rect.left,ct->rect.bottom-1); 
			dc->LineTo(ct->rect.right,ct->rect.bottom-1); 
			 
			//linea derecha observe que se pinta dos veces para 
			//dar el efecto de redondeada en la puntas 
 
			dc->SelectStockObject(BLACK_PEN); 
			dc->MoveTo(ct->rect.right-1,ct->rect.top-1); 
			dc->LineTo(ct->rect.right-1,ct->rect.bottom-1); 
 
		} 
		else 
		{ 
			if ((iCont+1) != m_iSelectTab) 
			{ 
				dc->SelectObject(&Dark); 
				dc->MoveTo(ct->rect.right-1,ct->rect.top+2); 
				dc->LineTo(ct->rect.right-1,ct->rect.bottom-2); 
			} 
				 
			 
		} 
		//se dibuja el icono 
		int nMode = dc->SetBkMode(TRANSPARENT); 
		CSize m_sChar=dc->GetTextExtent(ct->lpMsg,strlen(ct->lpMsg)); 
		if (m_sizeImag.cx+m_sChar.cx < ct->rect.Width()-8)   
		{ 
			Image.Draw(dc,ct->uIcon,CPoint(ct->rect.left+2,ct->rect.top+2),ILD_TRANSPARENT); 
			rectText=ct->rect; 
			rectText.left+=m_sizeImag.cx+8; 
			rectText.right-=2; 
			dc->DrawText(ct->lpMsg,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER); 
			CToolTip.SetToolRect(this,iCont+1,CRect(0,0,0,0)); 
		} 
		else 
		{ 
			//verificamos si se puede poner algun texto o 
			//por lo memos el icono 
			if (m_sizeImag.cx < ct->rect.Width()) 
			{ 
				Image.Draw(dc,ct->uIcon,CPoint(ct->rect.left+2,ct->rect.top+2),ILD_TRANSPARENT); 
				rectText=ct->rect; 
				rectText.left+=m_sizeImag.cx+8; 
				rectText.right-=5; 
				CString m_cadBreak=ct->lpMsg; 
				int c=0; 
				int cont=m_cadBreak.GetLength(); 
				while(cont > 1 ) 
				{ 
					CString m_scadtemp=m_cadBreak+"..."; 
					CSize coor=dc->GetTextExtent(m_scadtemp,m_scadtemp.GetLength()); 
					if(coor.cx > rectText.Width()) 
						m_cadBreak=m_cadBreak.Left(m_cadBreak.GetLength()-1); 
					else 
						break; 
					cont--; 
 
				} 
				m_cadBreak+=_T("..."); 
				rectText.right+=3; 
				dc->DrawText(m_cadBreak,rectText,DT_SINGLELINE|DT_LEFT|DT_VCENTER); 
				CToolTip.SetToolRect(this,iCont+1,&ct->rect); 
			} 
			 
		} 
		dc->SetBkMode(nMode); 
		 
		// Modified By SunZhenyu 
		dc->SelectObject(oldPen); 
	}	 
	 
	dc->SelectObject(m_fontOld); 
} 
 
void CGuiTabWnd::SetImageList(UINT nBitmapID, int cx, int nGrow, COLORREF crMask) 
{ 
	CBitmap cbmp; 
	BITMAP bmp; 
	Image.Create(nBitmapID,cx,nGrow,crMask); 
	cbmp.LoadBitmap(nBitmapID); 
	cbmp.GetBitmap(&bmp); 
	Image.Add(&cbmp,crMask); 
	m_sizeImag=CSize(cx,bmp.bmHeight);	 
	 
} 
 
CWnd* CGuiTabWnd::GetActiveWnd () const 
{ 
		return m_Numtabs == -1 ? NULL :  
		((CGuiTab*) m_pArray [m_Numtabs])->pParent; 
} 
 
BOOL CGuiTabWnd::FindItem(HWND hWnd) 
{ 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		if (ct->pParent->GetSafeHwnd() == hWnd) 
		    return TRUE; 
	} 
	return FALSE; 
 
} 
 
CWnd*  CGuiTabWnd::GetNumWnd(int m_numtab) const 
{ 
        if (m_numtab > m_Numtabs) 
			return NULL; 
		else 
		{ 
			if (m_pArray.GetSize() < 1) return NULL; 
			CWnd* pw=((CGuiTab*) m_pArray [m_numtab])->pParent; 
			if (HIWORD(pw)== NULL) return NULL; 
			else 
			  return ((CGuiTab*) m_pArray [m_numtab])->pParent; 
		} 
} 
 
void CGuiTabWnd::UpdateCaption(CWnd* pWnd,CString m_Title) 
{ 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		if (ct->pParent->GetSafeHwnd() == pWnd->GetSafeHwnd()) 
		{ 
			CString x=ct->lpMsg; 
			if(x!=m_Title) 
			{ 
				ct->lpMsg=m_Title; 
				GetParentFrame()->SendMessage(WM_SIZE); 
				RecalLayout(); 
				Invalidate(); 
				UpdateWindow(); 
			} 
			break; 
		} 
	} 
	 
} 
void CGuiTabWnd::ShowTitle(CString m_Caption) 
{ 
	if (m_ActualTitle==TRUE) 
	{ 
		CWnd* pParent=GetParent(); 
		pParent->SetWindowText(m_Caption); 
		pParent->SendMessage(WM_COMMAND,WM_SHOWTITLE); 
	} 
	 
} 
void CGuiTabWnd::Addtab(CWnd *pParent, CString lpMsg, UINT uIcon) 
{ 
	ASSERT_VALID(pParent); 
	m_pArray.SetAtGrow(m_Numtabs,new CGuiTab(pParent,lpMsg,uIcon)); 
	if (m_Numtabs==0) 
	{ 
	//	ShowTitle(lpMsg); 
		pParent->ShowWindow(SW_SHOW); 
		m_iSelectTab=m_Numtabs; 
	} 
	else 
		pParent->ShowWindow(SW_HIDE); 
	m_Numtabs++; 
	if (m_alnTab==ALN_TOP)	 
		pParent->ShowWindow(SW_SHOWMAXIMIZED); 
	if (m_style == S3D) 
		CToolTip.AddTool(this,lpMsg,CRect(0,0,0,0),m_Numtabs); 
	RecalLayout(); 
} 
 
 
void CGuiTabWnd::DeleteTab(int m_numtab) 
{ 
	if (m_numtab < m_Numtabs) 
	{ 
		CGuiTab* ctn=(CGuiTab*) m_pArray[m_numtab]; 	 
		CWnd* pParen=ctn->pParent; 
		if (m_alnTab!=ALN_TOP) 
			ASSERT_VALID(pParen); 
		m_Numtabs--; 
		/* Modified By SunZhenyu 2003/8/22, Add next 1 lines. */ 
		delete	ctn; 
		m_pArray.RemoveAt(m_numtab,1); 
		if (m_Numtabs >0) 
		{ 
			if (m_iSelectTab == m_numtab) 
			{ 
				m_iSelectTab=0; 
				CGuiTab* ctn =(CGuiTab*) m_pArray[m_iSelectTab]; 
				CWnd* pParentNew=ctn->pParent; 
				ASSERT_VALID(pParentNew); 
				pParentNew->ShowWindow(SW_SHOW); 
			} 
			RecalLayout(); 
		} 
		 
	} 
} 
 
void CGuiTabWnd::OnSize(UINT nType, int cx, int cy)  
{ 
	CWnd::OnSize(nType, cx, cy); 
	if (m_Numtabs > 0) 
		RecalLayout(); 
	 
} 
 
 
void CGuiTabWnd::SetCurtab(int m_numtab) 
{ 
	if (m_numtab < m_Numtabs && m_numtab != m_iSelectTab ) 
	{ 
		CGuiTab* ctn=(CGuiTab*) m_pArray[m_numtab];  
		CWnd* pParentNew= ctn->pParent; 
		CGuiTab* ct =(CGuiTab*) m_pArray[m_iSelectTab]; 
		CWnd* pParentActual=ct->pParent; 
		ASSERT_VALID(pParentNew); 
		ASSERT_VALID(pParentActual); 
		if (m_alnTab==ALN_TOP)	 
		{ 
			pParentNew->BringWindowToTop(); 
		} 
		else 
		{ 
			pParentActual->ShowWindow(SW_HIDE); 
			pParentNew->ShowWindow(SW_SHOW); 
		} 
		 
		m_iSelectTab=m_numtab; 
		Invalidate(); 
		UpdateWindow(); 
	} 
 
	// Modified By SunZhenYu, 2003/10/28, add next 3 lines 
	CWnd * pParent = GetParent(); 
	if( pParent ) 
	{ 
		WPARAM wParam = GetDlgCtrlID(); 
		NMHDR hdr; 
		hdr.hwndFrom = GetSafeHwnd(); 
		hdr.idFrom = GetDlgCtrlID(); 
		hdr.code = TCN_SELCHANGE; 
		pParent->SendMessage( WM_NOTIFY, wParam, (LPARAM)&hdr); 
	} 
} 
 
int CGuiTabWnd::GetCurtab() 
{ 
	return m_iSelectTab; 
} 
 
 
void CGuiTabWnd::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CWnd::OnLButtonDown(nFlags, point); 
	for (int iCont=0; iCont< m_Numtabs;iCont++) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[iCont]; 
		if (ct->rect.PtInRect(point) != 0) 
		{ 
            SetCurtab(iCont); 
			ShowTitle(ct->lpMsg); 
			return; 
		} 
		 
	} 
 
} 
 
void CGuiTabWnd::SetStyle(Style estyle) 
{ 
	m_style=estyle; 
} 
 
// Modified By SunZhenyu, 2003/10/28, add the next function 
CRect CGuiTabWnd::GetTabRect( int m_numtab ) 
{ 
	if( m_numtab >= 0 && m_numtab < m_Numtabs ) 
	{ 
		CGuiTab* ct=(CGuiTab*) m_pArray[m_numtab]; 
		CRect	rect = ct->rect; 
		ClientToScreen( &rect ); 
		return rect; 
	} 
	return CRect(0,0,0,0); 
} 
 
// Modified By SunZhenyu, 2003/11/09, add the next function 
void CGuiTabWnd::SetSelectTabColor( COLORREF clrBK, COLORREF clrText ) 
{ 
	m_clrSelectTabBK	=	clrBK; 
	m_clrSelectTabText	=	clrText; 
} 
 
// Modified By SunZhenyu, 2003/11/11, add the next 1 function 
LRESULT CGuiTabWnd::OnColorChange(WPARAM wParam, LPARAM lParam) 
{ 
	SetSelectTabColor( wParam, lParam ); 
	Invalidate( ); 
	return 0L; 
}