| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083 | 
							- // SheetCtrl.cpp : implementation file
 
- //
 
- #include "stdafx.h"
 
- #include "TabCtrl.h"
 
- #include "Misc.h"
 
- #ifdef _DEBUG
 
- #define new DEBUG_NEW
 
- #undef THIS_FILE
 
- static char THIS_FILE[] = __FILE__;
 
- #endif
 
- #define TEXT_PAD			7
 
- #define SPIN_PAD			3
 
- #define SHIFT_UNITS			10
 
- #define COLOR_WHITE			RGB(255, 255, 255)
 
- #define COLOR_GRAY			RGB(128, 128, 128)
 
- #define COLOR_MEDGRAY		GetSysColor(COLOR_BTNFACE)
 
- #define COLOR_DARKGRAY		RGB(64, 64, 64)
 
- #define ID_SCROLL_TIMER		0x1010
 
- #define VK_TILDAE			0xC0
 
- /////////////////////////////////////////////////////////////////////////////
 
- // CTabCtrlEx
 
- CTabCtrlEx::CTabCtrlEx()
 
- {
 
- 	m_nStyle = 0;
 
- 	m_nActiveTab = -1;
 
- 	m_nTabHeight = 19;
 
- 	m_btnState[0] = BtnUp;
 
- 	m_btnState[1] = BtnUp;
 
- 	m_bBtnEnabled[0] = false;
 
- 	m_bBtnEnabled[1] = false;
 
- 	m_nLeftShifted = 0;
 
- 	m_nPrevWidth = 0;
 
- 	m_pFntText = NULL;
 
- 	m_pFntBoldText = NULL;
 
- 	m_bSetFocusToNewlySelectedTab = true;
 
- 	m_SelectedColor = (COLORREF)GetSysColor(COLOR_BTNFACE);
 
- 	m_NonSelectedColor = RGB(255, 251, 233);
 
- }
 
- CTabCtrlEx::~CTabCtrlEx()
 
- {
 
- 	if (m_pFntText)
 
- 		delete m_pFntText;
 
- 	m_pFntText = NULL;
 
- 	if (m_pFntBoldText)
 
- 		delete m_pFntBoldText;
 
- 	m_pFntBoldText = NULL;
 
- }
 
- BEGIN_MESSAGE_MAP(CTabCtrlEx, CWnd)
 
- 	//{{AFX_MSG_MAP(CTabCtrlEx)
 
- 	ON_WM_PAINT()
 
- 	ON_WM_CREATE()
 
- 	ON_WM_LBUTTONDOWN()
 
- 	ON_WM_MOUSEMOVE()
 
- 	ON_WM_LBUTTONUP()
 
- 	ON_WM_SIZE()
 
- 	ON_WM_TIMER()
 
- 	ON_WM_SHOWWINDOW()
 
- 	//}}AFX_MSG_MAP
 
- END_MESSAGE_MAP()
 
- /////////////////////////////////////////////////////////////////////////////
 
- // CTabCtrlEx message handlers
 
- BOOL CTabCtrlEx::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
 
- {
 
- 	// Get the sheet styles alone
 
- 	m_nStyle = short(dwStyle & 0xFFFF);
 
- 	// Remove the sheet styles and create the window
 
- 	dwStyle &= 0xFFFF0000;
 
- 	
 
- 	// If the window border style is set, change it to sheet border style
 
- 	if (dwStyle & WS_BORDER)
 
- 	{
 
- 		m_nStyle |= SCS_BORDER;
 
- 		dwStyle &= ~WS_BORDER;
 
- 	}
 
- 	// Register the class
 
- 	WNDCLASS wndClass;
 
- 	memset(&wndClass, 0, sizeof(wndClass));
 
- 	
 
- 	BOOL bRet = false;
 
- 	HINSTANCE hInst = AfxGetInstanceHandle();
 
- 	if (::GetClassInfo(hInst, SHEET_CLASSNAME, &wndClass))
 
- 	{
 
- 		bRet = (wndClass.style == SHEET_CLASSTYLE);
 
- 	}
 
- 	if (bRet == FALSE)
 
- 	{
 
- 		memset(&wndClass, 0, sizeof(wndClass));
 
- 		wndClass.style = SHEET_CLASSTYLE;
 
- 		wndClass.lpfnWndProc = ::DefWindowProc;
 
- 		wndClass.cbClsExtra = wndClass.cbWndExtra = 0;
 
- 		wndClass.hInstance = hInst;
 
- 		wndClass.hIcon = NULL;
 
- 		wndClass.hCursor = NULL;
 
- 		wndClass.hbrBackground = NULL;
 
- 		wndClass.lpszMenuName = NULL;
 
- 		wndClass.lpszClassName = SHEET_CLASSNAME;
 
- 		if ((bRet = AfxRegisterClass(&wndClass)) == FALSE)
 
- 			ASSERT(FALSE);
 
- 	}
 
- 	if (bRet)
 
- 		bRet = CWnd::Create(SHEET_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
 
- 	return bRet;
 
- }
 
- int CTabCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct) 
 
- {
 
- 	if (CWnd::OnCreate(lpCreateStruct) == -1)
 
- 		return -1;
 
- 	
 
- 	// Create the brushes, pens
 
- 	m_brSelectedTab.CreateSolidBrush(m_SelectedColor);
 
- 	m_brNonSelectedTab.CreateSolidBrush(m_NonSelectedColor);
 
- 	m_penGray.CreatePen(PS_SOLID, 1, RGB(172, 168, 153));
 
- 	m_penBlack.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
 
- 	SetTabHeight(m_nTabHeight);
 
- 	return 0;
 
- }
 
- void CTabCtrlEx::SetTabHeight(int nTabHeight)
 
- {
 
- 	m_nTabHeight = nTabHeight;
 
- 	// Delete the old font and create a new one
 
- 	if (m_pFntText)
 
- 		delete m_pFntText;
 
- 	m_pFntText = new CFont;
 
- 	
 
- 	if (m_pFntText)
 
- 	{
 
- 		// Set the regular font
 
- 		m_pFntText->CreateFont(-(m_nTabHeight*7/10), 0, 0, 0, FW_LIGHT, FALSE, FALSE, 0, DEFAULT_CHARSET,
 
- 			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Arial Unicode MS"));
 
- 	}
 
- 	// Delete the old font and create a new one
 
- 	if (m_pFntBoldText)
 
- 		delete m_pFntBoldText;
 
- 	m_pFntBoldText = new CFont;
 
- 	if (m_pFntBoldText)
 
- 	{
 
- 		// Set the bold font
 
- 		m_pFntBoldText->CreateFont(-(m_nTabHeight*7/10), 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, 0, DEFAULT_CHARSET,
 
- 			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Arial Unicode MS"));
 
- 	}
 
- }
 
- bool CTabCtrlEx::AddItem(const CString& csTabTitle, CWnd* pTabWnd)
 
- {
 
- 	return InsertItem((int)m_Tabs.GetSize(), csTabTitle, pTabWnd);
 
- }
 
- bool CTabCtrlEx::InsertItem(int nTab, const CString& csTabTitle, CWnd* pTabWnd)
 
- {
 
- 	CTab tab;
 
- 	tab.csTitle = csTabTitle;
 
- 	tab.pWnd = pTabWnd;
 
- 	tab.lWidth = GetTextWidth(csTabTitle);
 
- 	tab.clrUnderline = -1;
 
- 	m_Tabs.InsertAt(nTab, tab);
 
- 	
 
- 	if(nTab <= m_nActiveTab)
 
- 		m_nActiveTab++;
 
- 	// Redraw the window
 
- 	RedrawWindow();
 
- 	
 
- 	return true;
 
- }
 
- bool CTabCtrlEx::ReplaceItem(int nTab, const CString &csTabTitle, CWnd* pTabWnd)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		if(m_Tabs[nTab].pWnd)
 
- 			m_Tabs[nTab].pWnd->ShowWindow(SW_HIDE);
 
- 		m_Tabs[nTab].csTitle = csTabTitle;
 
- 		m_Tabs[nTab].pWnd = pTabWnd;
 
- 		m_Tabs[nTab].lWidth = GetTextWidth(csTabTitle);
 
- 		if(pTabWnd)
 
- 			pTabWnd->ShowWindow(SW_SHOW);
 
- 		SetActiveTab(m_nActiveTab);
 
- 		return true;
 
- 	}
 
- 	return false;
 
- }
 
- bool CTabCtrlEx::DeleteItem(int nTab)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		// Remove the tab
 
- 		m_Tabs.RemoveAt(nTab);
 
- 		// Set the new active tab
 
- 		if (nTab == GetActiveTab())
 
- 		{
 
- 			if(nTab > 0)
 
- 				nTab--;
 
- 			SetActiveTab(nTab, true);
 
- 		}
 
- 		
 
- 		// Redraw the window
 
- 		RedrawWindow();
 
- 		return true;
 
- 	}
 
- 	return false;
 
- }
 
- bool CTabCtrlEx::DeleteAllItems()
 
- {
 
- 	// Remove all the tab
 
- 	m_Tabs.RemoveAll();
 
- 		
 
- 	// Reset the active tab
 
- 	m_nActiveTab = -1;
 
- 	// Redraw the window
 
- 	RedrawWindow();
 
- 	return true;
 
- }
 
- void CTabCtrlEx::UnderlineTabTitle(int nTab, COLORREF clr)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		m_Tabs[nTab].clrUnderline = clr;
 
- 		Invalidate();
 
- 	}
 
- }
 
- int CTabCtrlEx::GetTextWidth(const CString& csText)
 
- {
 
- 	CDC *pDC = GetDC();
 
- 	if (pDC)
 
- 	{
 
- 		// Select the font
 
- 		CFont *pPrevFont = pDC->SelectObject(m_pFntBoldText);
 
- 		
 
- 		// Get the width
 
- 		int nWidth = pDC->GetTextExtent(csText).cx;
 
- 		
 
- 		// Restore the font
 
- 		pDC->SelectObject(pPrevFont);
 
- 		ReleaseDC(pDC);
 
- 		return (nWidth + 2*TEXT_PAD);
 
- 	}
 
- 	
 
- 	return 0;
 
- }
 
- int CTabCtrlEx::GetDisplayWidth()
 
- {
 
- 	CRect rcWnd;
 
- 	GetClientRect(rcWnd);
 
- 	
 
- 	// If all the tabs cannot fit, then the spinner is visiable
 
- 	if (GetTabsWidth() > rcWnd.Width())
 
- 		return rcWnd.Width()-GetSpinnerWidth();
 
- 	return rcWnd.Width();
 
- }
 
- int CTabCtrlEx::GetTabsWidth()
 
- {
 
- 	int nWidth = 0;
 
- 	// Get the width for all tabs
 
- 	for (int iTab=0; iTab<m_Tabs.GetSize(); iTab++)
 
- 		nWidth += m_Tabs[iTab].lWidth;
 
- 	nWidth += TEXT_PAD;
 
- 	return nWidth;
 
- }
 
- int CTabCtrlEx::GetSpinnerWidth()
 
- {
 
- 	int nSpinWidth = m_nTabHeight-2*1;
 
- 	return (2*nSpinWidth + SPIN_PAD);
 
- }
 
- void CTabCtrlEx::GetFullRect(CRect& rcTab)
 
- {
 
- 	// Get the area of the full sheet window
 
- 	GetClientRect(rcTab);
 
- 	
 
- 	// Get the full tab area
 
- 	if (m_nStyle & SCS_TOP)
 
- 		rcTab.bottom = m_nTabHeight;
 
- 	else
 
- 		rcTab.top = rcTab.Height()-m_nTabHeight;
 
- }
 
- void CTabCtrlEx::GetTabListRect(CRect& rcTab)
 
- {
 
- 	// Get the full tab area
 
- 	GetFullRect(rcTab);
 
- 	
 
- 	// Get the area for the tabs
 
- 	if (m_nStyle & SCS_TOP)
 
- 		rcTab.bottom -= 1;
 
- 	else
 
- 		rcTab.top += 1;
 
- }
 
- void CTabCtrlEx::GetTabRect(int nTab, CRect& rcTab)
 
- {
 
- 	// Get the area for the tabs
 
- 	GetTabListRect(rcTab);
 
- 	rcTab.top += 2;
 
- 	int nLeft = 0;
 
- 	// Get the area for the current tab
 
- 	for (int iTab=0; iTab<m_Tabs.GetSize(); iTab++)
 
- 	{
 
- 		if (iTab == nTab)
 
- 		{
 
- 			rcTab.left = nLeft;
 
- 			rcTab.right = nLeft+m_Tabs[iTab].lWidth;
 
- 			break;
 
- 		}
 
- 		nLeft += m_Tabs[iTab].lWidth;
 
- 	}
 
- }
 
- void CTabCtrlEx::GetSpinnerRect(CRect& rcSpin)
 
- {
 
- 	// Get the area for the tabs
 
- 	GetTabListRect(rcSpin);
 
- 	// If all the tabs cannot fit, then show the spinner
 
- 	if (GetTabsWidth() > rcSpin.Width())
 
- 		rcSpin.left = rcSpin.right-GetSpinnerWidth();
 
- 	// Set the spinner width to zero
 
- 	else
 
- 		rcSpin.SetRectEmpty();
 
- }
 
- void CTabCtrlEx::GetButtonRect(int nBtn, CRect& rcBtn)
 
- {
 
- 	GetSpinnerRect(rcBtn);
 
- 	rcBtn.DeflateRect(SPIN_PAD, 0, 0, 0);
 
- 	
 
- 	rcBtn.DeflateRect(1, 1);
 
- 	if (nBtn == 0)
 
- 		rcBtn.right = rcBtn.left + rcBtn.Width()/2;
 
- 	else if (nBtn == 1)
 
- 		rcBtn.left = rcBtn.left + rcBtn.Width()/2;
 
- 	else
 
- 		rcBtn.SetRectEmpty();
 
- }
 
- CString CTabCtrlEx::GetTabTitle(int nTab)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 		return m_Tabs[nTab].csTitle;
 
- 	return "";
 
- }
 
- bool CTabCtrlEx::SetTabTitle(int nTab, const CString& csTabTitle)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		m_Tabs[nTab].csTitle = csTabTitle;
 
- 		m_Tabs[nTab].lWidth = GetTextWidth(csTabTitle);
 
- 		// Redraw the window
 
- 		RedrawWindow();
 
- 		return true;
 
- 	}
 
- 	return false;
 
- }
 
- bool CTabCtrlEx::SetTabItemData(int nTab, long lItemData)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		m_Tabs[nTab].lItemData = lItemData;
 
- 		return true;
 
- 	}
 
- 	return false;
 
- }
 
- long CTabCtrlEx::GetTabItemData(int nTab)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		return m_Tabs[nTab].lItemData;
 
- 	}
 
- 	return -1;
 
- }
 
- int CTabCtrlEx::GetActiveTab()
 
- {
 
- 	return m_nActiveTab;
 
- }
 
- int CTabCtrlEx::GetTabCount()
 
- {
 
- 	return (int)m_Tabs.GetSize();
 
- }
 
- void CTabCtrlEx::SetActiveTab(int nTab, bool bNotify)
 
- {
 
- 	ActivateTab(nTab, bNotify);
 
- }
 
- void CTabCtrlEx::ActivateTab(int nTab, bool bNotify, bool bOnSize)
 
- {
 
- 	if ((nTab >= 0) && (nTab < m_Tabs.GetSize()))
 
- 	{
 
- 		// Set the new active tab
 
- 		int nOldTab = GetActiveTab();
 
- 		m_nActiveTab = nTab;
 
- 		
 
- 		// Resize the tab windows
 
- 		ResizeTabWindow(nOldTab, GetActiveTab(), bNotify, bOnSize);
 
- 		// Make the tab visible
 
- 		MakeTabVisible(GetActiveTab());
 
- 		// Redraw the tabs
 
- 		if (bOnSize)
 
- 			InvalidateRect(NULL);
 
- 		else
 
- 			RedrawWindow();
 
- 	}
 
- }
 
- void CTabCtrlEx::ResizeTabWindow(int nOldTab, int nNewTab, bool bNotify, bool bOnSize)
 
- {
 
- 	long lOldItemData = -1;
 
- 	long lNewItemData = -1;
 
- 	if ((nOldTab >= 0) && nOldTab < GetTabCount())
 
- 	{
 
- 		lOldItemData = m_Tabs[nOldTab].lItemData;
 
- 		CWnd* pPrevWnd = m_Tabs[nOldTab].pWnd;
 
- 		// Hide the previous tab
 
- 		if (pPrevWnd && IsWindow(pPrevWnd->m_hWnd))
 
- 			pPrevWnd->ShowWindow(SW_HIDE);
 
- 	}
 
- 	if ((nNewTab >= 0) && nNewTab < GetTabCount())
 
- 	{
 
- 		CRect rcWnd;
 
- 		//GetClientRect(rcWnd);
 
- 		GetWindowRect(rcWnd);
 
- 		lNewItemData = m_Tabs[nNewTab].lItemData;
 
- 		CWnd *pParentWnd = GetParent();
 
- 		if (pParentWnd && IsWindow(pParentWnd->m_hWnd))
 
- 			pParentWnd->ScreenToClient(rcWnd);
 
- 		
 
- 		int nPad = 0;
 
- 		CWnd* pNextWnd = m_Tabs[nNewTab].pWnd;;
 
- 		// Show the new tab and bring it to the top, set the focus to the new tab
 
- 		if (pNextWnd && IsWindow(pNextWnd->m_hWnd))
 
- 		{
 
- 			// Resize the tab window
 
- 			if (m_nStyle & SCS_TOP)
 
- 			{
 
- 				pNextWnd->SetWindowPos(&wndTop, rcWnd.left+nPad, rcWnd.top+m_nTabHeight+nPad,
 
- 					rcWnd.Width()-2*nPad, rcWnd.Height()-m_nTabHeight-2*nPad, SWP_SHOWWINDOW);
 
- 			}
 
- 			else
 
- 			{
 
- 				pNextWnd->SetWindowPos(&wndTop, rcWnd.left+nPad, rcWnd.top+nPad,
 
- 					rcWnd.Width()-2*nPad, rcWnd.Height()-m_nTabHeight-2*nPad, SWP_SHOWWINDOW);
 
- 			}
 
- 			if(m_bSetFocusToNewlySelectedTab)
 
- 			{
 
- 				// Set the focus
 
- 				if (bOnSize == FALSE)
 
- 					pNextWnd->SetFocus();
 
- 			}
 
- 		}
 
- 	}
 
- 	if (bNotify)
 
- 	{
 
- 		// Send a notification message to the parent window
 
- 		CWnd *pParentWnd = GetParent();
 
- 		if (pParentWnd && IsWindow(pParentWnd->m_hWnd))
 
- 		{
 
- 			NMTABCHANGE nmTab;
 
- 			ZeroMemory(&nmTab, sizeof(nmTab));
 
- 			nmTab.hdr.code = SN_SETACTIVETAB;
 
- 			nmTab.hdr.hwndFrom = GetSafeHwnd();
 
- 			nmTab.hdr.idFrom = GetDlgCtrlID();
 
- 			nmTab.lOldTab = nOldTab;
 
- 			nmTab.lNewTab = nNewTab;
 
- 			nmTab.lOldItemData = lOldItemData;
 
- 			nmTab.lNewItemData = lNewItemData;
 
- 			
 
- 			pParentWnd->SendMessage(WM_NOTIFY, (WPARAM) nmTab.hdr.idFrom, (LPARAM) &nmTab);
 
- 		}
 
- 	}
 
- }
 
- void CTabCtrlEx::MakeTabVisible(int nTab)
 
- {
 
- 	CRect rcTab;
 
- 	GetTabRect(nTab, rcTab);
 
- 	rcTab.OffsetRect(-m_nLeftShifted, 0);
 
- 	if (rcTab.right > GetDisplayWidth())
 
- 		m_nLeftShifted += (rcTab.right-GetDisplayWidth()+TEXT_PAD);
 
- 	
 
- 	GetTabRect(nTab, rcTab);
 
- 	rcTab.OffsetRect(-m_nLeftShifted, 0);
 
- 	if (rcTab.left <= 0)
 
- 	{
 
- 		m_nLeftShifted += rcTab.left;
 
- 		if (m_nLeftShifted < 0)
 
- 		{
 
- 			ASSERT(FALSE);
 
- 			m_nLeftShifted = 0;
 
- 		}
 
- 	}
 
- }
 
- void CTabCtrlEx::OnPaint() 
 
- {
 
- 	CPaintDC dc(this); // device context for painting
 
- 	
 
- 	CRect rcUpdate(0, 0, 0, 0);
 
- 	
 
- 	// Enable spinners
 
- 	EnableSpinners();
 
- 	if (m_nActiveTab < 0)
 
- 	{
 
- 		// Set the first window to be the active tab
 
- 		ActivateTab(0, true, true);
 
- 	}
 
- 	// Draw the tabs
 
- 	DrawTabs(&dc);
 
- }
 
- void CTabCtrlEx::EnableSpinners()
 
- {
 
- 	int nDispWidth = GetDisplayWidth();
 
- 	
 
- 	if (nDispWidth >= GetTabsWidth())
 
- 	{
 
- 		// We have enough space, disable the spinners
 
- 		m_nLeftShifted = 0;
 
- 		m_bBtnEnabled[0] = false;
 
- 		m_bBtnEnabled[1] = false;
 
- 	}
 
- 	else
 
- 	{
 
- 		// Enable/Disable the spinner buttons
 
- 		m_bBtnEnabled[0] = (m_nLeftShifted > 0);
 
- 		m_bBtnEnabled[1] = ((m_nLeftShifted+nDispWidth) < GetTabsWidth());
 
- 	}
 
- }
 
- void CTabCtrlEx::DrawTabs(CDC *pDC)
 
- {
 
- 	// Draw the bar
 
- 	DrawBar(pDC);
 
- 	CRect rcTab;
 
- 	// Draw all the tabs but the active tab
 
- 	for (int iTab=0; iTab<m_Tabs.GetSize(); iTab++)
 
- 	{
 
- 		if (iTab == GetActiveTab())
 
- 			continue;
 
- 		GetTabRect(iTab, rcTab);
 
- 		rcTab.OffsetRect(-m_nLeftShifted, 0);
 
- 		DrawTab(iTab, pDC, rcTab);
 
- 	}
 
- 	// Draw the active tab
 
- 	GetTabRect(GetActiveTab(), rcTab);
 
- 	rcTab.OffsetRect(-m_nLeftShifted, 0);
 
- 	if (GetActiveTab() < m_Tabs.GetSize())
 
- 		DrawTab(GetActiveTab(), pDC, rcTab);
 
- 	// Draw the spinner buttons
 
- 	DrawSpinner(pDC);
 
- }
 
- void CTabCtrlEx::DrawBar(CDC* pDC)
 
- {
 
- 	CRect rcBar;
 
- 	GetFullRect(rcBar);
 
- 	// Set the background color for the tabs
 
- 	pDC->FillRect(rcBar, &m_brNonSelectedTab);
 
- 	if (m_nStyle & SCS_BOLD)
 
- 	{
 
- 		// Draw the line
 
- 		if (m_nStyle & SCS_TOP)
 
- 		{
 
- 			pDC->MoveTo(CPoint(rcBar.left, rcBar.bottom-1));
 
- 			pDC->LineTo(CPoint(rcBar.right, rcBar.bottom-1));
 
- 		}
 
- 		else
 
- 		{
 
- 			pDC->MoveTo(rcBar.TopLeft());
 
- 			pDC->LineTo(CPoint(rcBar.right, rcBar.top));
 
- 		}
 
- 	}
 
- }
 
- void CTabCtrlEx::DrawTab(int nTab, CDC *pDC, CRect& rcTab)
 
- {
 
- 	if(nTab < 0)
 
- 		return;
 
- 	DrawTabEx(nTab, pDC, rcTab);
 
- 	return;
 
- 	// Paint the text centered.
 
- 	CPoint ptArr[5];
 
- 	if (m_nStyle & SCS_TOP)
 
- 	{
 
- 		ptArr[0] = CPoint(rcTab.left, rcTab.bottom-1);
 
- 		ptArr[1] = CPoint(rcTab.left+TEXT_PAD, rcTab.top);
 
- 		ptArr[2] = CPoint(rcTab.right, rcTab.top);
 
- 		ptArr[3] = CPoint(rcTab.right+TEXT_PAD, rcTab.bottom);
 
- 		ptArr[4] = CPoint(rcTab.left, rcTab.bottom);
 
- 	}
 
- 	else
 
- 	{
 
- 		ptArr[0] = rcTab.TopLeft();
 
- 		ptArr[1] = CPoint(rcTab.left+TEXT_PAD, rcTab.bottom-1);
 
- 		ptArr[2] = CPoint(rcTab.right, rcTab.bottom-1);
 
- 		ptArr[3] = CPoint(rcTab.right+TEXT_PAD, rcTab.top-1);
 
- 		ptArr[4] = rcTab.TopLeft();
 
- 	}
 
- 	
 
- 	// Draw the Tab
 
- 	CRgn rgn;
 
- 	if (rgn.CreatePolygonRgn(ptArr, 4, WINDING) == FALSE)
 
- 		return;
 
- 	CFont *pFont = NULL;
 
- 	if (nTab == GetActiveTab())
 
- 	{
 
- 		pDC->FillRgn(&rgn, &m_brSelectedTab);
 
- 		pFont = m_pFntBoldText;
 
- 	}
 
- 	else
 
- 	{
 
- 		pDC->FillRgn(&rgn, &m_brNonSelectedTab);
 
- 		pFont = m_pFntText;
 
- 	}
 
- 	CPen *pPen = NULL;
 
- 	if ((m_nStyle & SCS_BOLD) == 0)
 
- 		pPen = &m_penGray;
 
- 	
 
- 	CPen *pPrevPen = pDC->SelectObject(pPen);
 
- 	pDC->Polyline(ptArr, 4);
 
- 	pDC->SelectObject(pPrevPen);
 
- 	
 
- 	// Draw the text
 
- 	CFont *pPrevFont = pDC->SelectObject(pFont);
 
- 	rcTab.right += TEXT_PAD;
 
- 	pDC->SetBkMode(TRANSPARENT);
 
- 	pDC->DrawText(m_Tabs[nTab].csTitle, rcTab, DT_CENTER|DT_VCENTER|DT_END_ELLIPSIS);
 
- 	pDC->SelectObject(pPrevFont);
 
- 	if (m_Tabs[nTab].clrUnderline != -1)
 
- 	{
 
- 		pDC->Draw3dRect(CRect(rcTab.left+TEXT_PAD+2, rcTab.bottom-2, rcTab.right-TEXT_PAD-2, rcTab.bottom),
 
- 			m_Tabs[nTab].clrUnderline, m_Tabs[nTab].clrUnderline);
 
- 	}
 
- }
 
- void CTabCtrlEx::DrawTabEx(int nTab, CDC *pDC, CRect& rcTab)
 
- {
 
- 	if(nTab < 0)
 
- 		return;
 
- 	CRect rcOrig(rcTab);
 
- 	rcTab.OffsetRect(1, 1);
 
- 	CFont *pFont = NULL;
 
- 	if (nTab == GetActiveTab())
 
- 	{
 
- 		pDC->FillSolidRect(rcTab, m_SelectedColor);
 
- 		pFont = m_pFntBoldText;
 
- 	}
 
- 	else
 
- 	{
 
- 		pDC->FillSolidRect(rcTab, m_NonSelectedColor);
 
- 		pFont = m_pFntText;
 
- 	}
 
- 	//Don't draw a line on the item before the selected tab
 
- 	if (nTab != GetActiveTab()-1)
 
- 	{
 
- 		int nBottomOffset = 0;
 
- 		int nTopOffset = 0;
 
- 		CPen *pPen = NULL;
 
- 		if (nTab == GetActiveTab())
 
- 		{
 
- 			pPen = &m_penBlack;
 
- 			nTopOffset = -1;
 
- 		}
 
- 		else
 
- 		{
 
- 			pPen = &m_penGray;
 
- 			nBottomOffset = 3;
 
- 			nTopOffset = 2;
 
- 		}
 
- 		CPen *pPrevPen = pDC->SelectObject(pPen);
 
- 		pDC->MoveTo(CPoint(rcTab.right-1, rcTab.bottom-nBottomOffset));
 
- 		pDC->LineTo(CPoint(rcTab.right-1, rcTab.top+nTopOffset));
 
- 		pDC->SelectObject(pPrevPen);
 
- 	}
 
- 	// Draw the text
 
- 	CFont *pPrevFont = pDC->SelectObject(pFont);
 
- 	pDC->SetBkMode(TRANSPARENT);
 
- 	pDC->DrawText(m_Tabs[nTab].csTitle, rcOrig, DT_CENTER|DT_VCENTER|DT_END_ELLIPSIS);
 
- 	pDC->SelectObject(pPrevFont);
 
- }
 
- void CTabCtrlEx::DrawSpinner(CDC *pDC)
 
- {
 
- 	CRect rcSpin;
 
- 	GetSpinnerRect(rcSpin);
 
- 	if (rcSpin.Width() == 0)
 
- 		return;
 
- 	// Set the background color
 
- 	pDC->FillRect(rcSpin, &m_brNonSelectedTab);
 
- 	// Draw the line
 
- 	pDC->MoveTo(CPoint(rcSpin.left+1, rcSpin.top));
 
- 	pDC->LineTo(CPoint(rcSpin.left+1, rcSpin.bottom));
 
- 	rcSpin.DeflateRect(SPIN_PAD, 0, 0, 0);
 
- 	CRect rcBtn;
 
- 	GetButtonRect(0, rcBtn);
 
- 	DrawButton(pDC, rcBtn, m_btnState[0], ArrowLeft, m_bBtnEnabled[0]);
 
- 	GetButtonRect(1, rcBtn);
 
- 	DrawButton(pDC, rcBtn, m_btnState[1], ArrowRight, m_bBtnEnabled[1]);
 
- }
 
- void CTabCtrlEx::DrawButton(CDC *pDC, CRect& rcBtn, ButtonState btnState,
 
- 	ButtonStyle btnStyle, bool bEnable)
 
- {
 
- 	// Draw the arrow
 
- 	CPoint ptArr[3];
 
- 	int x = rcBtn.left + rcBtn.Width()/3;
 
- 	int y = rcBtn.top + rcBtn.Height()/2;	
 
- 	long lHeight = rcBtn.Height()/4;
 
- 	CPen *pPen = NULL;
 
- 	// Change pen if button disabled
 
- 	if (bEnable == false)
 
- 		pPen = &m_penGray;
 
- 	
 
- 	CPen *pPrevPen = pDC->SelectObject(pPen);
 
- 	// Draw the left arrow
 
- 	if (btnStyle == ArrowLeft)
 
- 	{
 
- 		for (int iHt=0; iHt<=lHeight; x++, iHt++)
 
- 		{
 
- 			pDC->MoveTo(x, y-iHt);
 
- 			pDC->LineTo(x, y+iHt+1);
 
- 		}
 
- 	}
 
- 	// Draw the right arrow
 
- 	else
 
- 	{
 
- 		for (int iHt=lHeight; iHt>=0; x++, iHt--)
 
- 		{
 
- 			pDC->MoveTo(x, y-iHt);
 
- 			pDC->LineTo(x, y+iHt+1);
 
- 		}
 
- 	}
 
- 	pDC->SelectObject(pPrevPen);
 
- 	// Draw the button frame
 
- 	if (btnState == BtnUp)
 
- 		pDC->Draw3dRect(rcBtn, COLOR_WHITE, COLOR_DARKGRAY);
 
- 	else// if (btnState == BtnDown)
 
- 		pDC->Draw3dRect(rcBtn, COLOR_DARKGRAY, COLOR_WHITE);
 
- }
 
- void CTabCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) 
 
- {
 
- 	CRect rcBtn;
 
- 	bool bOnButton = false;
 
- 	for (int iBtn=0; iBtn<2; iBtn++)
 
- 	{
 
- 		GetButtonRect(iBtn, rcBtn);
 
- 		if (rcBtn.PtInRect(point) && m_bBtnEnabled[iBtn])
 
- 		{
 
- 			m_btnState[iBtn] = BtnDown;
 
- 			bOnButton = true;
 
- 		}
 
- 	}
 
- 	if (bOnButton)
 
- 	{
 
- 		// Get the mouse capture
 
- 		SetCapture();
 
- 		// Start the timer message
 
- 		SetTimer(ID_SCROLL_TIMER, 100, NULL);
 
- 		// Redraw the buttons
 
- 		RedrawWindow();
 
- 	}
 
- 	
 
- 	CWnd::OnLButtonDown(nFlags, point);
 
- }
 
- void CTabCtrlEx::OnTimer(UINT_PTR nIDEvent) 
 
- {
 
- 	if (nIDEvent == ID_SCROLL_TIMER)
 
- 	{
 
- 		CPoint point(0, 0);
 
- 		GetCursorPos(&point);
 
- 		ScreenToClient(&point);
 
- 		ScrollTab(point);
 
- 		// Redraw the buttons and tabs
 
- 		RedrawWindow();
 
- 	}
 
- 	
 
- 	CWnd::OnTimer(nIDEvent);
 
- }
 
- void CTabCtrlEx::OnMouseMove(UINT nFlags, CPoint point) 
 
- {
 
- 	/*
 
- 	CRect rcBtn;
 
- 	bool bRedrawButton = false;
 
- 	for (int iBtn=0; iBtn<2; iBtn++)
 
- 	{
 
- 		GetButtonRect(iBtn, rcBtn);
 
- 		if (rcBtn.PtInRect(point) && m_bBtnEnabled[iBtn])
 
- 		{
 
- 			if (m_btnState[iBtn] != BtnHover)
 
- 			{
 
- 				m_btnState[iBtn] = BtnHover;
 
- 				bRedrawButton = true;
 
- 				
 
- 				// Get the mouse capture
 
- 				SetCapture();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			if (m_btnState[iBtn] != BtnUp)
 
- 			{
 
- 				m_btnState[iBtn] = BtnUp;
 
- 				bRedrawButton = true;
 
- 				// Release the mouse capture
 
- 				ReleaseCapture();
 
- 			}
 
- 		}
 
- 	}
 
- 	if (bRedrawButton)
 
- 	{
 
- 		// Redraw the buttons
 
- 		RedrawWindow();
 
- 	}
 
- 	*/
 
- 	
 
- 	CWnd::OnMouseMove(nFlags, point);
 
- }
 
- void CTabCtrlEx::OnLButtonUp(UINT nFlags, CPoint point)
 
- {
 
- 	// Release the mouse capture
 
- 	ReleaseCapture();
 
- 	// End the timer
 
- 	KillTimer(ID_SCROLL_TIMER);
 
- 	
 
- 	// Check and scroll the tabs
 
- 	ScrollTab(point);
 
- 	
 
- 	// Set the button state
 
- 	for (int iBtn=0; iBtn<2; iBtn++)
 
- 		m_btnState[iBtn] = BtnUp;
 
- 	
 
- 	// Redraw the buttons
 
- 	RedrawWindow();
 
- 	CWnd::OnLButtonUp(nFlags, point);
 
- }
 
- void CTabCtrlEx::ScrollTab(CPoint point)
 
- {
 
- 	CRect rcBtn;
 
- 	for (int iBtn=0; iBtn<2; iBtn++)
 
- 	{
 
- 		GetButtonRect(iBtn, rcBtn);
 
- 		if (rcBtn.PtInRect(point))
 
- 		{
 
- 			if (m_bBtnEnabled[iBtn])
 
- 			{
 
- 				m_btnState[iBtn] = BtnDown;
 
- 				if (iBtn == 0)
 
- 				{
 
- 					m_nLeftShifted -= SHIFT_UNITS;
 
- 					if (m_nLeftShifted < 0)
 
- 						m_nLeftShifted = 0;
 
- 				}
 
- 				else
 
- 				{
 
- 					m_nLeftShifted += SHIFT_UNITS;
 
- 				}	
 
- 			}
 
- 			else
 
- 			{
 
- 				m_btnState[iBtn] = BtnUp;
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			m_btnState[iBtn] = BtnUp;
 
- 		}
 
- 	}
 
- 	CRect rcSpin;
 
- 	GetSpinnerRect(rcSpin);
 
- 	if (rcSpin.PtInRect(point) == FALSE)
 
- 	{
 
- 		// Adjust for the shift
 
- 		point.Offset(m_nLeftShifted, 0);
 
- 		
 
- 		CRect rcTab;
 
- 		for (int iTab=0; iTab<m_Tabs.GetSize(); iTab++)
 
- 		{
 
- 			GetTabRect(iTab, rcTab);
 
- 			if (rcTab.PtInRect(point))
 
- 			{
 
- 				// Show the appropriate tab window
 
- 				ActivateTab(iTab, true);
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- void CTabCtrlEx::OnSize(UINT nType, int cx, int cy) 
 
- {
 
- 	CWnd::OnSize(nType, cx, cy);
 
- 	// Resize the tabs
 
- 	if (m_nLeftShifted && (cx > m_nPrevWidth))
 
- 	{
 
- 		int nDispWidth = cx-GetSpinnerWidth();
 
- 		if ((nDispWidth+m_nLeftShifted) >= GetTabsWidth())
 
- 		{
 
- 			m_nLeftShifted -= (cx-m_nPrevWidth);
 
- 			if (m_nLeftShifted <= GetSpinnerWidth())
 
- 				m_nLeftShifted = 0;
 
- 		}
 
- 	}
 
- 	ActivateTab(GetActiveTab(), false, true);
 
- 	
 
- 	m_nPrevWidth = cx;
 
- }
 
- BOOL CTabCtrlEx::PreTranslateMessage(MSG* pMsg) 
 
- {
 
- 	switch (pMsg->message)
 
- 	{
 
- 	case WM_KEYDOWN:
 
- 		if (CONTROL_PRESSED)
 
- 		{
 
- 			if (pMsg->wParam == VK_TILDAE)
 
- 			{
 
- 				SwitchTabs((GetKeyState(VK_SHIFT) & 0x8000) == 0);
 
- 				return TRUE;
 
- 			}
 
- 			else if (((pMsg->wParam - '1') >= 0) && ((pMsg->wParam - '1') < (UINT) m_Tabs.GetSize()))
 
- 			{
 
- 				// Set the new active tab
 
- 				ActivateTab((int)pMsg->wParam - '1', true);
 
- 				return TRUE;
 
- 			}
 
- 		}
 
- 		break;
 
- 	}
 
- 	
 
- 	return FALSE;
 
- }
 
- void CTabCtrlEx::SwitchTabs(bool bNext)
 
- {
 
- 	int nNewTab = GetActiveTab();
 
- 	if (bNext)
 
- 		nNewTab++;
 
- 	else
 
- 		nNewTab--;
 
- 	if (nNewTab < 0)
 
- 		nNewTab = (int)m_Tabs.GetSize()-1;
 
- 	else if (nNewTab >= m_Tabs.GetSize())
 
- 		nNewTab = 0;
 
- 	// Set the new active tab
 
- 	ActivateTab(nNewTab, true);
 
- }
 
- void CTabCtrlEx::OnShowWindow(BOOL bShow, UINT nStatus)
 
- {
 
- 	if (bShow)
 
- 	{
 
- 		// Show the active tab
 
- 		SetActiveTab(GetActiveTab(), false);
 
- 	}
 
- 	else
 
- 	{	
 
- 		// Hide the active tab
 
- 		if (GetActiveTab() >= 0)
 
- 		{
 
- 			CWnd* pWnd = m_Tabs[GetActiveTab()].pWnd;
 
- 			if (pWnd && IsWindow(pWnd->m_hWnd))
 
- 				pWnd->ShowWindow(SW_HIDE);
 
- 		}
 
- 	}
 
- }
 
 
  |