www.pudn.com > MDITab.rar > WindowTabCtrl.cpp


// WindowTabCtrl.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "resource.h"       // main symbols 
#include "WindowTabCtrl.h" 
#include "ViewManager.h" 
#include "PopupMenu.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define CX_BORDER  1 
#define CY_BORDER  1 
 
// TODO: Uncomment the ff. (__NO_RIGHTCLICK_SEL) if you do not wish to have the  
//       tab selected, when right-clicked. 
//#define  __NO_RIGHTCLICK_SEL 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CWindowTabCtrl 
 
CWindowTabCtrl::CWindowTabCtrl() : m_bDisplayIcons(TRUE) 
{ 
	m_crSelColor    = RGB(  0,  0, 255); 
	m_crUnselColor  = RGB( 50, 50,  50); 
	m_crDocModified = RGB(255,  0,   0); 
	 
	// Get the current font 
	LOGFONT lFont; 
	memset(&lFont, 0, sizeof(LOGFONT)); 
	NONCLIENTMETRICS ncm; 
	ncm.cbSize = sizeof(NONCLIENTMETRICS); 
	VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,  
		sizeof(NONCLIENTMETRICS), &ncm, 0)); 
	lFont = ncm.lfMessageFont;  
	 
	// Create the "Selected" font 
	m_SelFont.CreateFontIndirect(&lFont); 
	// Create the "UnSelected" font 
	m_UnselFont.CreateFontIndirect(&lFont); 
} 
 
CWindowTabCtrl::~CWindowTabCtrl() 
{ 
	m_SelFont.DeleteObject(); 
	m_UnselFont.DeleteObject(); 
} 
 
 
BEGIN_MESSAGE_MAP(CWindowTabCtrl, CTabCtrl) 
	//{{AFX_MSG_MAP(CWindowTabCtrl) 
	ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange) 
	ON_WM_CREATE() 
	ON_WM_RBUTTONDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWindowTabCtrl message handlers 
 
void CWindowTabCtrl::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	if (pNMHDR->hwndFrom == NULL) 
		return;                    // just to avoid level 4 compilation warning 
 
	int idx = GetCurSel(); 
 
	TCITEM tci; 
	tci.mask = TCIF_PARAM; 
	GetItem(idx, &tci); 
 
	CMDIChildWnd* pChild = reinterpret_cast(tci.lParam); 
 
	static_cast(AfxGetMainWnd())->MDIActivate(pChild); 
	*pResult = 0; 
} 
 
void CWindowTabCtrl::SetIconDisplay(BOOL bDisplayIt) 
{ 
	m_bDisplayIcons = bDisplayIt; 
	Invalidate(); 
} 
 
int CWindowTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CTabCtrl::OnCreate(lpCreateStruct) == -1) 
	{ 
		TRACE0(_T("OnCreate function call failed!")); 
		return -1; 
	} 
	ModifyStyle(0, TCS_OWNERDRAWFIXED); 
	 
	HFONT hFont  = reinterpret_cast(GetStockObject(DEFAULT_GUI_FONT)); 
	CFont* pFont = CFont::FromHandle(hFont); 
	SetFont(pFont); 
	 
	return 0; 
} 
 
/* 
void CWindowTabCtrl::PreSubclassWindow()  
{ 
	CTabCtrl::PreSubclassWindow(); 
	ModifyStyle(0, TCS_OWNERDRAWFIXED); //TODO must go! 
} 
*/ 
 
void CWindowTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	ASSERT(IsWindow(m_hWnd)); 
 
	CRect rcTab   =  CRect(&(lpDrawItemStruct->rcItem)); 
	int nTabIndex = lpDrawItemStruct->itemID; 
	if (nTabIndex < 0 || nTabIndex >= GetItemCount()) 
		return; 
	 
	BOOL bSelected = (nTabIndex == GetCurSel()); 
	 
	TCHAR szLabel[_MAX_PATH]; 
	TCITEM tci; 
	tci.mask       = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; 
	tci.pszText    = szLabel;      
	tci.cchTextMax = _MAX_PATH - 1;    	 
	if (!GetItem(nTabIndex, &tci))  
		return; 
	 
	CDC dc; 
	if (lpDrawItemStruct->hDC == NULL) 
		return; 
 
	if (!dc.Attach(lpDrawItemStruct->hDC))  
		return; 
	 
	DWORD dwStyle = GetStyle(); 
    rcTab.NormalizeRect(); 
	if ((dwStyle & TCS_BOTTOM) == 0) 
	{ 
		rcTab.DeflateRect(CX_BORDER, CY_BORDER); 
		rcTab.top += ::GetSystemMetrics(SM_CYEDGE); 
	} 
	 
	dc.SetBkMode(TRANSPARENT); 
	dc.FillSolidRect(rcTab, ::GetSysColor(COLOR_BTNFACE)); 
	 
	CMDIChildWnd* pChild = reinterpret_cast(tci.lParam); 
	if (pChild == NULL) 
		return; 
	// Get the active view attached to the active MDI child window. 
	CView* pView = reinterpret_cast(pChild->GetActiveView()); 
	if (pView == NULL) 
		return; 
	CDocument* pDoc = pView->GetDocument(); 
	if (pDoc == NULL) 
		return; 
 
	// Draw image 
	if (m_bDisplayIcons) 
	{ 
		CImageList*   pImageList = GetImageList(); 
		CMDIChildWnd* pViewFrame = reinterpret_cast(tci.lParam); 
        HICON hIcon = reinterpret_cast(GetClassLong(pViewFrame->m_hWnd, GCL_HICONSM)); 
		pImageList->Replace(tci.iImage/*nTabIndex*/, hIcon);  // nTabIndex 
 
		if (pImageList && tci.iImage >= 0)  
		{ 
			rcTab.left += 4;//TODO--dc.GetTextExtent(_T(" ")).cx;		// Set a little margin 
			 
			// Get the height of image  
			IMAGEINFO info; 
			pImageList->GetImageInfo(tci.iImage, &info); 
			CRect ImageRect(info.rcImage); 
			int nYpos = rcTab.top; 
			 
			pImageList->Draw(&dc, tci.iImage, CPoint(rcTab.left, nYpos), ILD_TRANSPARENT); 
			rcTab.left += ImageRect.Width(); 
		} 
	} 
	 
	if (bSelected)  
	{ 
		if (pDoc->IsModified()) 
			dc.SetTextColor(m_crDocModified); 
		else 
			dc.SetTextColor(m_crSelColor); 
		dc.SelectObject(&m_SelFont); 
		rcTab.top -= ::GetSystemMetrics(SM_CYEDGE); 
	}  
	else  
	{ 
		if (pDoc->IsModified()) 
			dc.SetTextColor(m_crDocModified); 
		else 
			dc.SetTextColor(m_crUnselColor); 
		dc.SelectObject(&m_UnselFont); 
	} 
	 
	dc.DrawText(szLabel, rcTab, DT_SINGLELINE | DT_VCENTER | DT_CENTER); 
	dc.Detach(); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CWindowTabCtrl operations 
 
void CWindowTabCtrl::SetColors(COLORREF crSelColor, COLORREF crUnselColor,  
							   COLORREF crDocModified) 
{ 
	if ((crSelColor != CLR_NONE) || (crSelColor != CLR_DEFAULT)) 
		m_crSelColor    = crSelColor; 
	if ((crUnselColor != CLR_NONE) || (crUnselColor != CLR_DEFAULT)) 
		m_crUnselColor  = crUnselColor; 
	if ((crDocModified != CLR_NONE) || (crDocModified != CLR_DEFAULT)) 
		m_crDocModified = crDocModified; 
 
	Invalidate(); 
} 
 
void CWindowTabCtrl::SetFonts(CFont* pSelFont, CFont* pUnselFont) 
{ 
	ASSERT(pSelFont && pUnselFont); 
 
	LOGFONT lFont; 
	memset(&lFont, 0, sizeof(LOGFONT)); 
	int nSelHeight = 0, nUnselHeight = 0; 
 
	m_SelFont.DeleteObject(); 
	m_UnselFont.DeleteObject(); 
 
	pSelFont->GetLogFont(&lFont); 
	m_SelFont.CreateFontIndirect(&lFont); 
	nSelHeight = lFont.lfHeight; 
 
	pUnselFont->GetLogFont(&lFont); 
	m_UnselFont.CreateFontIndirect(&lFont); 
	nUnselHeight = lFont.lfHeight; 
 
	SetFont((nSelHeight > nUnselHeight) ? &m_SelFont : &m_UnselFont); 
} 
 
void CWindowTabCtrl::SetFonts(CFont* pFont, BOOL bSelFont) 
{ 
	ASSERT(pFont); 
 
	LOGFONT lFont; 
	memset(&lFont, 0, sizeof(LOGFONT)); 
 
	if (bSelFont) 
	{ 
		m_SelFont.DeleteObject(); 
		pFont->GetLogFont(&lFont); 
		m_SelFont.CreateFontIndirect(&lFont); 
		SetFont(&m_SelFont); 
	} 
	else 
	{ 
		m_UnselFont.DeleteObject(); 
		pFont->GetLogFont(&lFont); 
		m_UnselFont.CreateFontIndirect(&lFont); 
		SetFont(&m_UnselFont); 
	} 
} 
 
void CWindowTabCtrl::SetFonts(int nSelWeight,   BOOL bSelItalic,   BOOL bSelUnderline, 
						  int nUnselWeight, BOOL bUnselItalic, BOOL bUnselUnderline) 
{ 
	// Free any memory currently used by the fonts. 
	m_SelFont.DeleteObject(); 
	m_UnselFont.DeleteObject(); 
 
	// Get the current font 
	LOGFONT lFont; 
	memset(&lFont, 0, sizeof(LOGFONT)); 
	CFont* pFont = GetFont(); 
	if (pFont) 
		pFont->GetLogFont(&lFont); 
	else  
	{ 
		NONCLIENTMETRICS ncm; 
		ncm.cbSize = sizeof(NONCLIENTMETRICS); 
		VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,  
			sizeof(NONCLIENTMETRICS), &ncm, 0)); 
		lFont = ncm.lfMessageFont;  
	} 
 
	// Create the "Selected" font 
	lFont.lfWeight    = static_cast(nSelWeight); 
	lFont.lfItalic    = static_cast(bSelItalic); 
	lFont.lfUnderline = static_cast(bSelUnderline); 
	m_SelFont.CreateFontIndirect(&lFont); 
 
	// Create the "Unselected" font 
	lFont.lfWeight    = static_cast(nUnselWeight); 
	lFont.lfItalic    = static_cast(bUnselItalic); 
	lFont.lfUnderline = static_cast(bUnselUnderline); 
	m_UnselFont.CreateFontIndirect(&lFont); 
 
	SetFont((nSelWeight > nUnselWeight) ? &m_SelFont : &m_UnselFont); 
} 
 
void CWindowTabCtrl::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
#ifndef __NO_RIGHTCLICK_SEL 
	// Select the tab which is clicked and activate the attached view 
    TCHITTESTINFO   hti; 
     
    hti.pt = CPoint(GetMessagePos()); 
    ScreenToClient(&hti.pt); 
    int iTab = HitTest(&hti); 
    if (iTab < 0) 
        return; 
	SetCurSel(iTab);                    // Select it 
 
	TCITEM tci; 
	tci.mask = TCIF_PARAM; 
	GetItem(iTab, &tci); 
 
	CMDIChildWnd* pChild = reinterpret_cast(tci.lParam); 
	static_cast(AfxGetMainWnd())->MDIActivate(pChild); 
#endif //__NO_RIGHTCLICK_SEL 
 
	// Now, process the popup menu for the tab control 
	POINT  ptScreen = point; 
	// Convert the mouse point to screen coordinates since that is what is used by 
	// the TrackPopupMenu() function. 
	ClientToScreen(&ptScreen); 
	CPopupMenu cMenu; 
	cMenu.CreatePopupMenu(); 
	 
	cMenu.AppendMenu(MF_STRING, ID_WINDOW_CLOSE, _T("&Close")); 
	cMenu.AppendMenu(MF_STRING, ID_FILE_SAVE, _T("&Save\tCtrl+S")); 
	cMenu.AppendMenu(MF_STRING, ID_FILE_SAVE_AS, _T("Save &As...")); 
	cMenu.AppendMenu(MF_SEPARATOR); 
	cMenu.AppendMenu(MF_STRING, ID_FILE_PRINT, _T("&Print\tCtrl+P")); 
	cMenu.AppendMenu(MF_STRING, ID_FILE_PRINT_PREVIEW, _T("Print Pre&view")); 
	 
	cMenu.LoadToolBarResource(IDR_TABVIEW_MENU); 
	cMenu.RemapMenu(&cMenu); 
	cMenu.EnableMenuItems(&cMenu, AfxGetMainWnd()); 
	 
    // insert a separator item at the top 
    cMenu.InsertMenu(0, MF_BYPOSITION | MF_SEPARATOR, 0, _T("")); 
 
    // insert title item 
    // note: item is not selectable (disabled) but not grayed 
    cMenu.InsertMenu(0, MF_BYPOSITION | MF_STRING | MF_DISABLED, 0, _T("Active View Tab")); 
 
    ::SetMenuDefaultItem(cMenu.m_hMenu, 0, TRUE); 
 
	cMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd()); 
	 
	cMenu.DestroyMenu(); 
	 
	CTabCtrl::OnRButtonDown(nFlags, point); 
} 
 
void CWindowTabCtrl::SetTabStyle(BOOL bButtons, BOOL bFlatButtons) 
{ 
	DWORD dwAdd          = 0; 
	DWORD dwCurrentStyle = GetStyle(); 
 
	if (!bButtons && (dwCurrentStyle & TCS_BUTTONS)) 
	{ 
		ModifyStyle(TCS_BUTTONS | TCS_FLATBUTTONS, 0, 0); 
		return; 
	} 
	else if (!bButtons) 
		return; 
		 
	if (bButtons && (dwCurrentStyle & TCS_BUTTONS) &&  
		(dwCurrentStyle & TCS_FLATBUTTONS)) 
		return; 
 
	if (bButtons) 
		dwAdd |= TCS_BUTTONS; 
	if (bFlatButtons) 
		dwAdd |= TCS_FLATBUTTONS; 
	ModifyStyle(0, dwAdd, 0); 
}