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

📄 ftab.cpp

📁 一种简单的股票软件源代码,编译后可以实时显示证券行情
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	dc.LineTo(rc.right, rc.top);
	if (m_dwFtabStyle & FTS_FULLBORDER) {
		dc.MoveTo(rc.right-1, rc.top);
		dc.LineTo(rc.right-1, rc.bottom-1);
		dc.LineTo(rc.left,  rc.bottom-1);
		dc.LineTo(rc.left,  rc.top);
	} else {
		dc.MoveTo(rc.left, rc.top);
	}
	dc.LineTo(rcCurTab.TopLeft());
	dc.SelectObject(pOldPen);
}

//////////////////
// Handle mouse click: select new tab, if any. Notify parent, of course
//
void CFolderTabCtrl::OnLButtonDown(UINT nFlags, CPoint pt)
{
	int iTab = HitTest(pt);
	if (iTab>=0 && iTab!=m_iCurItem) {
		SelectItem(iTab);
		NMFOLDERTAB nm;
		nm.hwndFrom = m_hWnd;
		nm.idFrom = GetDlgCtrlID();
		nm.code = FTN_TABCHANGED;
		nm.iItem = iTab;
		CWnd* pParent = GetParent();
		pParent->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
	}
}

//////////////////
// Find which tab is under mouse, -1 if none
//
int CFolderTabCtrl::HitTest(CPoint pt)
{
	CRect rc;
	GetClientRect(&rc);
	rc.left += m_cxButtons;
	if (rc.PtInRect(pt)) {
		int xOrigin = m_cxButtons - GetTab(m_iFirstTab)->GetRect().left;
		pt.x -= xOrigin;
		int n = GetItemCount();
		for (int i=0; i<n; i++) {
			if (GetTab(i)->HitTest(pt))
				return i;
		}
	}
	return -1;
}

//////////////////
// Select ith tab. Returns index selected
//
int CFolderTabCtrl::SelectItem(int iTab)
{
	int count = GetItemCount();
	if (iTab<0 || iTab>=count)
		return -1;		// bad
	if (iTab == m_iCurItem)
		return iTab;	// already selected

	if (m_iCurItem < count)
		InvalidateTab(m_iCurItem);		// invalidate old tab (repaint)

	m_iCurItem = iTab;				// set new selected tab
	InvalidateTab(m_iCurItem);		// repaint new tab
	
	return m_iCurItem;
}

//////////////////
/// Invalidate a tab: invaldate its rect
//
void CFolderTabCtrl::InvalidateTab(int iTab, BOOL bErase)
{
	CRect rc = GetTab(iTab)->GetRect();
	int xOrigin = m_cxButtons - GetTab(m_iFirstTab)->GetRect().left;
	rc += CPoint(xOrigin,0);
	InvalidateRect(rc, bErase);
}

//////////////////
// Load folder tab control from resource string:
// newline-separated list of tab names.
//
BOOL CFolderTabCtrl::Load(UINT nIDRes)
{
	CString s;
	if (!s.LoadString(nIDRes))
		return FALSE;

	CString sTab;
	for (int i=0; AfxExtractSubString(sTab, s, i); i++) {
		AddItem(sTab);
	}
	return TRUE;
}

//////////////////
// Add a tab.
//
int CFolderTabCtrl::AddItem(LPCTSTR lpszText)
{
	m_lsTabs.AddTail(new CFolderTab(lpszText));
	RecomputeLayout();
	return m_lsTabs.GetCount() - 1;
}

//////////////////
// Remove tab at given index.
//
BOOL CFolderTabCtrl::RemoveItem(int iPos)
{
	POSITION pos = m_lsTabs.FindIndex(iPos);
	if (pos) {
		CFolderTab* pTab = (CFolderTab*)m_lsTabs.GetAt(pos);
		m_lsTabs.RemoveAt(pos);
		delete pTab;
	}
	RecomputeLayout();
	return pos!=NULL;
}

CFolderTab* CFolderTabCtrl::GetTab(int iPos)
{
	POSITION pos = m_lsTabs.FindIndex(iPos);
	return pos ? static_cast<CFolderTab*>(m_lsTabs.GetAt(pos)) : NULL;
}

//////////////////
// Recalculate layout based on having added or removed a tab.
//
void CFolderTabCtrl::RecomputeLayout()
{
	CClientDC dc(this);
	CFont* pOldFont = dc.SelectObject(&m_fontNormal);
	int x = 0;
	int n = GetItemCount();
	CFolderTab* pTab;
	for (int i=0; i<n; i++) {
		pTab = GetTab(i);
		if (pTab) 
			x += pTab->ComputeRgn(dc, x) - CXOFFSET;
	}
	dc.SelectObject(pOldFont);

	m_cxDesired = m_cxButtons;
	if (pTab) {
		CRect rc = pTab->GetRect();
		m_cxDesired += rc.right;
	}
}

//////////////////
// Folder tabs changed size: reposition scroll buttons.
//
void CFolderTabCtrl::OnSize(UINT nType, int cx, int cy)
{
	if (m_wndButton[0].m_hWnd) {
		int w = cy;
		CRect rc(0,0,w,cy);
		for (int i=FTBPREV; i<=FTBNEXT; i++) {
			m_wndButton[i-1].MoveWindow(&rc);
			rc += CPoint(w,0);
		}
		UpdateButtons();
	}
}

//////////////////
// Determine enabled state of scroll buttons
//
void CFolderTabCtrl::UpdateButtons()
{
	if (m_wndButton[0].m_hWnd && !m_lsTabs.IsEmpty()) {
		// enable prev button iff more tabs to left.
		m_wndButton[0].EnableWindow(m_iFirstTab>0);

		// enable next button iff more tabs to right
		CRect rc;
		GetClientRect(&rc);
		int xOrigin = m_cxButtons - GetTab(m_iFirstTab)->GetRect().left;
		CRect rcLast = ((CFolderTab*)m_lsTabs.GetTail())->GetRect();
		m_wndButton[1].EnableWindow(xOrigin + rcLast.right>rc.right);
	}
}

//////////////////
// User clicked next button: increment starting tab and repaint
//
void CFolderTabCtrl::OnNextTab()
{
	if (m_iFirstTab < m_lsTabs.GetCount()-1) {
		m_iFirstTab++;
		Invalidate();
		UpdateButtons();
	}
}

//////////////////
// User clicked prev button: decrement starting tab and repaint
//
void CFolderTabCtrl::OnPrevTab()
{
	if (m_iFirstTab > 0) {
		m_iFirstTab--;
		Invalidate();
		UpdateButtons();
	}
}

////////////////////////////////////////////////////////////////
// CFolderButton
//
IMPLEMENT_DYNAMIC(CFolderButton, CButton)
BEGIN_MESSAGE_MAP(CFolderButton, CButton)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_TIMER()
END_MESSAGE_MAP()

//////////////////
// Draw sroll button: draw a black triangle.
//
void CFolderButton::DrawItem(LPDRAWITEMSTRUCT lpDis)
{
	DRAWITEMSTRUCT& dis = *lpDis;
	CDC& dc = *CDC::FromHandle(dis.hDC);
	CRect rc;
	GetClientRect(&rc);

	// fill background with 3D face color
	dc.FillSolidRect(&rc,GetSysColor(COLOR_3DFACE));

	// shift southeast if button is pressed (bDown)
	BOOL bDown = dis.itemState & ODS_SELECTED;
	if (bDown) {
		rc += CPoint(1,1);
	}

	// draw line above to match folder tabs
	CPen pen(PS_SOLID,1,
		dis.itemState & ODS_DISABLED ? GetSysColor(COLOR_3DSHADOW) : RGB(0,0,0));
	CPen* pOldPen = dc.SelectObject(&pen);
	dc.MoveTo(rc.TopLeft());
	dc.LineTo(rc.right,rc.top);

	// Draw 3D highlight rect for 3D look
	CRect rc2=rc;
	for (int i=0; i<2; i++) {
		dc.Draw3dRect(&rc2,
			GetSysColor(bDown ? COLOR_3DFACE : COLOR_3DHIGHLIGHT),
			GetSysColor(COLOR_3DSHADOW));
		rc2.right--;
		rc2.bottom--;
	}

	// Draw triangle pointing the right way. Use shadow color if disabled.
	CSize szArrow = CSize(4,7);
	int cyMargin = (rc.Height()-szArrow.cy)/2;
	int cxMargin = (rc.Width()-szArrow.cx)/2;
	int x, incr;
	if (dis.CtlID==FTBNEXT) {
		x = rc.left + cxMargin;
		incr = 1;
	} else {
		x = rc.right - cxMargin - 1;
		incr = -1;
	}
	int y = rc.top + cyMargin;
	int h = 7;
	for (int j=0; j<4; j++) {
		dc.MoveTo(x,y);
		dc.LineTo(x,y+h);
		h-=2;
		x += incr;
		y++;
	}
	dc.SelectObject(pOldPen);
}

//////////////////
// User clicked button.
//
void CFolderButton::OnLButtonDown(UINT nFlags, CPoint pt)
{
	Default();									 // will send WM_COMMAND to parent
	SetTimer(1,500,NULL);					 // set timer for continual scroll
	m_nTimerClick = 0;						 // counter for initial delay
}

//////////////////
// User let go the mouse.
//
void CFolderButton::OnLButtonUp(UINT nFlags, CPoint pt)
{
	KillTimer(1);								 // no more repeat
	Default();
}

//////////////////
// Double-click: treat as another click.
//
void CFolderButton::OnLButtonDblClk(UINT nFlags, CPoint pt)
{
	SendMessage(WM_LBUTTONDOWN,nFlags,MAKELONG(pt.x,pt.y));
}

//////////////////
// Timer click: send another WM_COMMMAND, as if button clicked.
//
void CFolderButton::OnTimer(UINT nIDEvent)
{
	if (IsWindowEnabled()) {
		if (m_nTimerClick++ == 0) {
			KillTimer(1);
			SetTimer(1,150,NULL);
		}
		GetParent()->SendMessage(WM_COMMAND, GetDlgCtrlID());
	} else {
		KillTimer(1);
	}
}

⌨️ 快捷键说明

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