www.pudn.com > clking_src.rar > GuiTabWnd.cpp
//-----------------------------------------------------------------------// // This is a part of the GuiLib MFC Extention. // // Autor : Francisco Campos // // (C) 2002 Francisco CamposAll 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; i message == 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; }