⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcgtabwnd.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{
			m_ToolTip.SetToolRect (this, i + 1, CRect (0, 0, 0, 0));
		}

		x += pTab->m_rect.Width () + 1;
		m_nTabsTotalWidth += pTab->m_rect.Width () + 1;

		if (m_bFlat)
		{
			//--------------------------------------------
			// In the flat mode tab is overlapped by next:
			//--------------------------------------------
			pTab->m_rect.right += m_nTabsHeight / 2;
		}

		pTab->m_strDisplayedText = pTab->m_strText;
	}

	if (m_bFlat || x < m_rectTabsArea.right)
	{
		m_nTabsTotalWidth += m_nTabsHeight / 2;
		dc.SelectObject(pOldFont);
		return;
	}

	//-----------------------------------------
	// Not enouth space to show the whole text.
	//-----------------------------------------
	int nTabWidth = m_rectTabsArea.Width () / m_iTabsNum;

	//------------------------------------
	// May be it's too wide for some tabs?
	//------------------------------------
	int nRest = 0;
	int nCuttedTabsNum = m_iTabsNum;

	for (i = 0; i < m_iTabsNum; i ++)
	{
		CBCGTabInfo* pTab = (CBCGTabInfo*) m_arTabs [i];
		ASSERT_VALID (pTab);

		if (pTab->m_nFullWidth < nTabWidth)
		{
			nRest += nTabWidth - pTab->m_nFullWidth;
			nCuttedTabsNum --;
		}
	}

	if (nCuttedTabsNum <= 0)
	{
		ASSERT (FALSE);	// Somethin wrong
		dc.SelectObject(pOldFont);
		return;
	}

	nTabWidth += nRest / nCuttedTabsNum;

	//----------------------------------
	// Last pass: set actual rectangles:
	//----------------------------------
	x = m_rectTabsArea.left;
	for (i = 0; i < m_iTabsNum; i ++)
	{
		CBCGTabInfo* pTab = (CBCGTabInfo*) m_arTabs [i];
		ASSERT_VALID (pTab);

		BOOL bIsTrucncated = pTab->m_nFullWidth > nTabWidth;
		int nCurrTabWidth = (bIsTrucncated) ? nTabWidth : pTab->m_nFullWidth;

		if (bIsTrucncated)
		{
			TruncateText (&dc, pTab->m_strDisplayedText, 
				nCurrTabWidth - TEXT_MARGIN - IMAGE_MARGIN - m_sizeImage.cx);
		}

		if (nTabWidth < m_sizeImage.cx + IMAGE_MARGIN)
		{
			// Too narrow!
			nCurrTabWidth = (m_rectTabsArea.Width () + TAB_BORDER_SIZE * 2) / m_iTabsNum;
			pTab->m_strDisplayedText.Empty ();
		}
		else
		{
			if (pTab->m_strDisplayedText.IsEmpty ())
			{
				nCurrTabWidth = m_sizeImage.cx + 2 * TEXT_MARGIN;
			}
		}

		pTab->m_rect = CRect (CPoint (x, m_rectTabsArea.top),
						CSize (nCurrTabWidth, m_rectTabsArea.Height ()));

		if (!m_bFlat)
		{
			pTab->m_rect.bottom -= 2;
			m_ToolTip.SetToolRect (this, i + 1, 
				bIsTrucncated ? pTab->m_rect : CRect (0, 0, 0, 0));
		}

		x += nCurrTabWidth + 1;
	}

	dc.SelectObject(pOldFont);
}
//***************************************************************************************
void CBCGTabWnd::Draw3DTab (CDC* pDC, CBCGTabInfo* pTab, BOOL bActive)
{
	ASSERT_VALID (pTab);
	ASSERT_VALID (pDC);

	const int iVertOffset = 2;
	const int iHorzOffset = 2;

	CRect rectTab = pTab->m_rect;
	
	if (!bActive)
	{
		rectTab.bottom -= iVertOffset;
	}

	CPen penLight (PS_SOLID, 1, ::GetSysColor (COLOR_3DHILIGHT));

	CPen* pOldPen = (CPen*) pDC->SelectObject (&penLight);
	ASSERT(pOldPen != NULL);

	pDC->MoveTo(rectTab.left, rectTab.top);
	pDC->LineTo(rectTab.left, rectTab.bottom - iVertOffset);

	pDC->SelectStockObject(BLACK_PEN);

	pDC->LineTo(rectTab.left + iHorzOffset, rectTab.bottom);
	pDC->LineTo(rectTab.right - iHorzOffset, rectTab.bottom);
	pDC->LineTo(rectTab.right, rectTab.bottom - iVertOffset);
	pDC->LineTo(rectTab.right, rectTab.top - 1);

	CPen penDkGray (PS_SOLID, 1, ::GetSysColor (COLOR_3DSHADOW));
	pDC->SelectObject(&penDkGray);

	pDC->MoveTo(rectTab.left + iHorzOffset + 1, rectTab.bottom - 1);
	pDC->LineTo(rectTab.right - iHorzOffset, rectTab.bottom - 1);
	pDC->LineTo(rectTab.right - 1, rectTab.bottom - iVertOffset);
	pDC->LineTo(rectTab.right - 1, rectTab.top - 1);

	if (bActive)
	{
		pDC->FillRect (CRect (CPoint (rectTab.left, rectTab.top - 3), 
							CSize (rectTab.Width (), 3)), &globalData.brBtnFace);
	}

	if (m_sizeImage.cx + IMAGE_MARGIN <= rectTab.Width ())
	{
		if (m_Images.GetSafeHandle () != NULL)
		{
			// Draw the tab's image:
			CRect rectImage = rectTab;

			rectImage.top += (rectTab.Height () - m_sizeImage.cy) / 2;
			rectImage.bottom = rectImage.top + m_sizeImage.cy;

			rectImage.left += IMAGE_MARGIN;
			rectImage.right = rectImage.left + m_sizeImage.cx;

			m_Images.Draw (pDC, pTab->m_uiIcon, rectImage.TopLeft (), ILD_TRANSPARENT);
		}

		// Finally, draw the tab's text
		CRect rcText = rectTab;
		rcText.left += m_sizeImage.cx + 2 * TEXT_MARGIN;

		pDC->DrawText (pTab->m_strDisplayedText, 
							rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
	}

	pDC->SelectObject (pOldPen);
}
//***************************************************************************************
void CBCGTabWnd::DrawFlatTab (CDC* pDC, CBCGTabInfo* pTab, BOOL /*bActive*/)
{
	ASSERT_VALID (pTab);
	ASSERT_VALID (pDC);

	CRect rectTab = pTab->m_rect;
	rectTab.bottom --;

	//----------------
	// Draw tab edges:
	//----------------
	#define POINTS_NUM	4
	POINT pts [POINTS_NUM];

	pts [0].x = rectTab.left;
	pts [0].y = rectTab.top;

	pts [1].x = rectTab.left + m_nTabsHeight / 2;
	pts [1].y = rectTab.bottom;

	pts [2].x = rectTab.right - m_nTabsHeight / 2;
	pts [2].y = rectTab.bottom;

	pts [3].x = rectTab.right;
	pts [3].y = rectTab.top;

	pDC->Polygon (pts, POINTS_NUM);

	//---------------
	// Draw tab text:
	//---------------
	pDC->DrawText (pTab->m_strDisplayedText, 
					rectTab, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
//***************************************************************************************
void CBCGTabWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CWnd::OnLButtonDown(nFlags, point);

	if (m_rectTabSplitter.PtInRect (point))
	{
		m_bTrackSplitter = TRUE;
		SetCapture ();
		return;
	}

	CWnd* pWndParent = GetParent ();
	ASSERT_VALID (pWndParent);

	for (int i = 0; i < m_iTabsNum; i ++)
	{
		CBCGTabInfo* pTab = (CBCGTabInfo*) m_arTabs [i];
		ASSERT_VALID (pTab);

		if (pTab->m_rect.PtInRect (point))
		{
			if (i != m_iActiveTab && m_rectTabsArea.PtInRect (point))
			{
				SetActiveTab (i);
				pWndParent->SendMessage (BCGM_CHANGE_ACTIVE_TAB, i);
			}

			return;
		}
	}

	CWnd* pWndTarget = FindTargetWnd (point);
	if (pWndTarget == NULL)
	{
		return;
	}

	ASSERT_VALID (pWndTarget);

	MapWindowPoints (pWndTarget, &point, 1);
	pWndTarget->SendMessage (WM_LBUTTONDOWN, nFlags, 
							MAKELPARAM (point.x, point.y));
}
//***************************************************************************************
void CBCGTabWnd::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CWnd::OnLButtonDblClk(nFlags, point);

	CWnd* pWndTarget = FindTargetWnd (point);
	if (pWndTarget == NULL)
	{
		return;
	}

	ASSERT_VALID (pWndTarget);

	MapWindowPoints (pWndTarget, &point, 1);
	pWndTarget->SendMessage (WM_LBUTTONDBLCLK, nFlags, 
							MAKELPARAM (point.x, point.y));
}
//****************************************************************************************
int CBCGTabWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (m_bFlat)
	{
		//-------------------
		// Create scrollbars:
		//-------------------
		CRect rectDummy (0, 0, 0, 0);
		m_wndScrollTabs.Create (WS_CHILD | WS_VISIBLE | SBS_HORZ, rectDummy,
			this, (UINT) -1);

		if (m_bSharedScroll)
		{
			m_wndScrollWnd.Create (WS_CHILD | WS_VISIBLE | SBS_HORZ, rectDummy,
				this, (UINT) -1);
		}

		//---------------------
		// Create active brush:
		//---------------------
		m_brActiveTab.CreateSolidBrush (GetActiveTabColor ());
	}
	else
	{
		//---------------------------------------
		// Text may be truncated. Create tooltip.
		//---------------------------------------
		m_ToolTip.Create (this, TTS_ALWAYSTIP);
		m_ToolTip.Activate (TRUE);
		m_ToolTip.BringWindowToTop ();
	}

	SetTabsHeight ();
	return 0;
}
//***************************************************************************************
BOOL CBCGTabWnd::SetImageList (UINT uiID, int cx, COLORREF clrTransp)
{
	if (m_bFlat)
	{
		ASSERT (FALSE);
		return FALSE;
	}

	if (!m_Images.Create (uiID, cx, 0, clrTransp))
	{
		return FALSE;
	}

	IMAGEINFO info;
	m_Images.GetImageInfo (0, &info);

	CRect rectImage = info.rcImage;
	m_sizeImage = rectImage.Size ();

	SetTabsHeight ();
	return TRUE;
}
//***************************************************************************************
BOOL CBCGTabWnd::OnEraseBkgnd(CDC* pDC)
{
	if (m_iTabsNum == 0)
	{
		CRect rectClient;
		GetClientRect (rectClient);
		pDC->FillRect (rectClient, &globalData.brBtnFace);
	}

	return TRUE;
}
//****************************************************************************************
BOOL CBCGTabWnd::PreTranslateMessage(MSG* pMsg) 
{
   	switch (pMsg->message)
	{
	case WM_KEYDOWN:
		if (m_iActiveTab != -1 &&
			::GetAsyncKeyState (VK_CONTROL) & 0x8000)	// Ctrl is pressed
		{
			switch (pMsg->wParam)
			{
			case VK_NEXT:
				SetActiveTab (m_iActiveTab == m_iTabsNum - 1 ? 0 : m_iActiveTab + 1);
				GetActiveWnd ()->SetFocus ();
				GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iActiveTab);
				break;

			case VK_PRIOR:
				SetActiveTab (m_iActiveTab == 0 ? m_iTabsNum - 1 : m_iActiveTab - 1);
				GetActiveWnd ()->SetFocus ();
				GetParent ()->SendMessage (BCGM_CHANGE_ACTIVE_TAB, m_iActiveTab);
				break;
			}
		}
		// Continue....

	case WM_SYSKEYDOWN:
	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_RBUTTONUP:
	case WM_MBUTTONUP:
	case WM_NCLBUTTONDOWN:
	case WM_NCRBUTTONDOWN:
	case WM_NCMBUTTONDOWN:
	case WM_NCLBUTTONUP:
	case WM_NCRBUTTONUP:
	case WM_NCMBUTTONUP:
	case WM_MOUSEMOVE:
		if (!m_bFlat)
		{
			m_ToolTip.RelayEvent(pMsg);
		}
		break;
	}

	return CWnd::PreTranslateMessage(pMsg);
}
//****************************************************************************************
CWnd* CBCGTabWnd::GetTabWnd (int iTab) const
{
	if (iTab >= 0 && iTab < m_iTabsNum)
	{
		CBCGTabInfo* pTab = (CBCGTabInfo*) m_arTabs [iTab];
		ASSERT_VALID (pTab);

		return pTab->m_pWnd;
	}
	else
	{
		return NULL;
	}
}
//******************************************************************************************
CWnd* CBCGTabWnd::GetActiveWnd () const
{
	return m_iActiveTab == -1 ? 
		NULL : 
		((CBCGTabInfo*) m_arTabs [m_iActiveTab])->m_pWnd;
}
//******************************************************************************************
void CBCGTabWnd::TruncateText (CDC* pDC, CString& strText, int nMaxWidth)
//--------------
// By Alan Fritz
//--------------
{
	ASSERT_VALID (pDC);

	if (strText.IsEmpty ())
	{
		return;
	}

	CString strFirstChar = strText.Left (1);
	if (pDC->GetTextExtent (strFirstChar).cx > nMaxWidth)
	{
		// Even first char can't be displayed!
		strText.Empty ();
		return;
	}

	const CString strEllipses (_T("..."));
	CString strNewText (strText);

	while (strText.GetLength () > 1 &&
		pDC->GetTextExtent (strNewText).cx > nMaxWidth)
	{
		strText = strText.Left (strText.GetLength () - 1);
		strNewText = strText + strEllipses;
	}

	if (strText.GetLength () == 1)
	{
		// Start remove dots from ellipses...
		while (!strNewText.IsEmpty () &&
			pDC->GetTextExtent (strNewText).cx > nMaxWidth)
		{
			strNewText = strNewText.Left (strNewText.GetLength () - 1);
		}
	}

	strText = strNewText;
}
//******************************************************************************************
void CBCGTabWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	if (!m_bFlat)
	{
		CWnd::OnHScroll (nSBCode, nPos, pScrollBar);
		return;
	}

	if (pScrollBar->GetSafeHwnd () == m_wndScrollWnd.GetSafeHwnd ())
	{
		static BOOL bInsideScroll = FALSE;

		if (m_iActiveTab != -1 && !bInsideScroll)
		{
			CWnd* pWndActive = GetActiveWnd ();
			ASSERT_VALID (pWndActive);

			WPARAM wParam = MAKEWPARAM (nSBCode, nPos);

			//----------------------------------
			// Pass scroll to the active window:
			//----------------------------------
			bInsideScroll = TRUE;
			pWndActive->SendMessage (WM_HSCROLL, wParam, 0);
			bInsideScroll = FALSE;

			m_wndScrollWnd.SetScrollPos (pWndActive->GetScrollPos (SB_HORZ));

			HideActiveWindowHorzScrollBar ();
			GetParent ()->SendMessage (BCGM_ON_HSCROLL, wParam);
		}

		return;
	}

	if (pScrollBar->GetSafeHwnd () != m_wndScrollTabs.GetSafeHwnd ())
	{
		CWnd::OnHScroll (nSBCode, nPos, pScrollBar);
		return;
	}

	int nPrevOffset = m_nTabsHorzOffset;
	const int nScrollOffset = 20;

	switch (nSBCode)
	{
	case SB_LINELEFT:
		m_nTabsHorzOffset -= nScrollOffset;
		break;

	case SB_LINERIGHT:
		m_nTabsHorzOffset += nScrollOffset;
		break;

	default:
		AdjustTabsScroll ();
		return;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -