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

📄 ftab.cpp

📁 这是过于VC制作带有tab选现视图的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			pParent -> SendMessage (WM_NOTIFY, nm.idFrom, (LPARAM) & nm);
		}
		delete m_editBox;
		m_editBox = NULL;
		DefEditBoxProc = NULL;
		UserPressedEnterOnTheEditBox = false;
	}
}


//////////////////
// Handle right mouse click: Notify parent, of course
//
void CFolderTabCtrl::OnRButtonDown(UINT nFlags, CPoint pt)
{
	int iTab = HitTest(pt);
	if (iTab >= 0) 
	{
		SelectItem (iTab);
	}

		// Create the pop-up menu items.
	HMENU hmenu = CreatePopupMenu ();
	AppendMenu (hmenu, MF_ENABLED | MF_STRING, ID_EDIT_ADDSHEET, "Add");
	AppendMenu (hmenu, MF_ENABLED | MF_STRING, ID_EDIT_DELETESHEET, "Delete");
	AppendMenu (hmenu, MF_ENABLED | MF_STRING, ID_EDIT_RENAMESHEET, "Rename");
	AppendMenu (hmenu, MF_SEPARATOR, NULL, "");
	AppendMenu (hmenu, MF_ENABLED | MF_STRING, ID_EDIT_SHEETS, "Properties...");
		
		// display menu next to the selected tab
	ClientToScreen ( & pt);
	TrackPopupMenuEx (hmenu, TPM_RIGHTBUTTON, pt.x, pt.y, m_hWnd, NULL);
	
		// cleanup   
	DestroyMenu (hmenu);
}


//////////////////
// 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();
	CFolderTab * tab = GetTab (m_iFirstTab);
	int xOrigin = 0;
	if (tab)
		xOrigin = m_cxButtons - tab -> GetRect().left;
	else
		xOrigin = m_cxButtons;
	rc += CPoint(xOrigin,0);
	InvalidateRect(rc, bErase);
}


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;
}


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


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;
}


void CFolderTabCtrl::RecomputeLayout()
{
	CClientDC dc(this);
	int x = 0;
	int n = GetItemCount();
	CFolderTab* pTab = NULL;
	for (int i=0; i<n; i++) 
	{
		pTab = GetTab(i);
		CFont* pOldFont = NULL;
			//  use the bigger of the two fonts for all extents since the 
			//  Selected font is bigger than the Normal font - elsewhise 
			//  some of the displayed selected tab characters are cut
		// if (i == m_iCurItem) 
			pOldFont = dc.SelectObject(&m_fontSelected);
		// else
		//	pOldFont = dc.SelectObject(&m_fontNormal);
		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;
	}
}


int CFolderTabCtrl::OnCreate(LPCREATESTRUCT lpcs)
{
	if (CWnd::OnCreate(lpcs)!=0)
		return -1;

	if (m_dwFtabStyle & FTS_BUTTONS) 
	{
		CRect rc;
		// for (int i=FTBPREV; i<=FTBNEXT; i++) 
		for (int i = FTBFIRST; i <= FTBLAST; i++) 
		{
			VERIFY (m_wndButton[i-1].Create (NULL,
					WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,rc,this,i));
		}
		m_cxButtons = FTS_NUMBUTTONS * CXBUTTON;
	}
	return 0;
}


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++) 
		for (int i = FTBFIRST; i <= FTBLAST; i++) 
		{
			m_wndButton[i-1].MoveWindow(&rc);
			rc += CPoint(w,0);
		}
		UpdateButtons();
	}
}


void CFolderTabCtrl::UpdateButtons()
{
	for (int i = FTBFIRST; i <= FTBLAST; i++) 
	{
		m_wndButton [i - 1].EnableWindow (TRUE);
	}
}


void CFolderTabCtrl::OnFirstTab()
{
	m_iFirstTab = 0;
	Invalidate();
	UpdateButtons();
}


void CFolderTabCtrl::OnNextTab()
{
	if (m_iFirstTab < m_lsTabs.GetCount() - 1) 
	{
		m_iFirstTab++;
		Invalidate();
		UpdateButtons();
	}
}


void CFolderTabCtrl::OnPrevTab()
{
	if (m_iFirstTab > 0) 
	{
		m_iFirstTab--;
		Invalidate();
		UpdateButtons();
	}
}


void CFolderTabCtrl::OnLastTab()
{
	m_iFirstTab = m_lsTabs.GetCount() - 1;
	Invalidate();
	UpdateButtons();
}


void CFolderTabCtrl::OnEditProperties()
{
	NMFOLDERTAB nm;
	nm.hwndFrom = m_hWnd;
	nm.idFrom = GetDlgCtrlID();
	nm.code = FTN_EDITSHEETS;
	nm.iItem = m_iCurItem;
	CWnd* pParent = GetParent();
	pParent->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
}


void CFolderTabCtrl::OnEditAddSheet()
{
	NMFOLDERTAB nm;
	nm.hwndFrom = m_hWnd;
	nm.idFrom = GetDlgCtrlID();
	nm.code = FTN_ADDSHEET;
	nm.iItem = m_iCurItem;
	CWnd* pParent = GetParent();
		//  note that the parent will need to call the AddItem method
		//  in order to complete this user event
	pParent->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
}


void CFolderTabCtrl::OnEditDeleteSheet()
{
	NMFOLDERTAB nm;
	nm.hwndFrom = m_hWnd;
	nm.idFrom = GetDlgCtrlID();
	nm.code = FTN_DELETESHEET;
	nm.iItem = m_iCurItem;
	CWnd* pParent = GetParent();
		//  note that the parent will need to call the RemoveItem method
		//  in order to complete this user event
	pParent->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
}


void CFolderTabCtrl::OnEditRenameSheet()
{
		//  get the position for the proposed edit box
	CRect rc = GetTab (m_iCurItem) -> GetRect ();
		//  make the edit box smaller than the tab trapezoid
	rc.top++;
	rc.left += m_cxButtons + CXOFFSET + CXMARGIN;
	rc.right += m_cxButtons - CXOFFSET - CXMARGIN;
	rc.bottom--;
		//  now throw up the transparent edit control
	if ( ! m_editBox)
	{
		m_editBox = new CEdit;
		m_editBox -> Create ( WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 
								rc, this, EditBoxId );
		CFolderTab * tab = GetTab (m_iCurItem);
		m_editBox -> SetWindowText ( tab -> GetText () );
		m_editBox -> SetFocus ();
			//  the limit on the length of the tab names is 40 characters minus 1
		m_editBox -> SetLimitText (40 - 1);
		int len = strlen (tab -> GetText ());
			//  move the cursor to the end of the text without selecting anything
		m_editBox -> SetSel (len, len);
		HWND EditWnd = m_editBox -> GetSafeHwnd ();
		DefEditBoxProc = (WNDPROC) GetWindowLong (EditWnd, GWL_WNDPROC);
		SetWindowLong (EditWnd, GWL_WNDPROC, (long) MyEditBoxProc);
		UserPressedEnterOnTheEditBox = false;
		EditBoxHandle = EditWnd;
	}
}


////////////////////////////////////////////////////////////////
// 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()


void CFolderButton::DrawItem(LPDRAWITEMSTRUCT lpDis)
{
	DRAWITEMSTRUCT& dis = *lpDis;
	CDC& dc = *CDC::FromHandle(dis.hDC);
	CRect rc;
	GetClientRect(&rc);
	dc.FillSolidRect(&rc,GetSysColor(COLOR_3DFACE));
	BOOL bDown = dis.itemState & ODS_SELECTED;
	if (bDown) {
		rc += CPoint(1,1);
	}

	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);
	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--;
	}

		//  this number needs to be odd so that will get 1 pixel at the end
		//  Paul had it set to 7 - Excel appears to have 9
	int arrowHeight = 9;  
		//  this number appears to be (arrowHeight / 2 + 1)
		//  Paul had this set to 4 - Excel appears to have 5
	int arrowWidth = 5;
	int cyMargin = (rc.Height() - arrowHeight) / 2;
	int cxMargin = (rc.Width() - arrowWidth) / 2;

		//  draw the arrows (left or right depending on button)
	int x = 0;
	int incr = 0;
	switch (dis.CtlID)
	{
	case FTBFIRST:
		x = rc.right - cxMargin - 1;
		incr = -1;
		break;
	case FTBPREV:
		x = rc.right - cxMargin - 2;
		incr = -1;
		break;
	case FTBNEXT:
		x = rc.left + cxMargin;
		incr = 1;
		break;
	case FTBLAST:
		x = rc.left + cxMargin - 1;
		incr = 1;
		break;
	}
	int y = rc.top + cyMargin;
	int h = arrowHeight;
	for (int j = 0; j < arrowWidth; j++) 
	{
		dc.MoveTo (x, y);
		dc.LineTo (x, y + h);
		h -= 2;
		x += incr;
		y++;
	}
		//  draw the vertical line for the first and last buttons
	if (dis.CtlID == FTBFIRST) 
	{
			//  the vertical line is before the arrow
		x--;
		y = rc.top + cyMargin;
		dc.MoveTo (x, y);
		dc.LineTo (x, y + arrowHeight);
	}
	if (dis.CtlID == FTBLAST) 
	{
			//  the vertical line is after the arrow
		x++;
		y = rc.top + cyMargin;
		dc.MoveTo (x, y);
		dc.LineTo (x, y + arrowHeight);
	}
	dc.SelectObject(pOldPen);
}


void CFolderButton::OnLButtonDown(UINT nFlags, CPoint pt)
{
	Default();
	SetTimer(1,500,NULL);
	m_iState = 0;
}


void CFolderButton::OnLButtonUp(UINT nFlags, CPoint pt)
{
	KillTimer(1);
	Default();
}


void CFolderButton::OnLButtonDblClk(UINT nFlags, CPoint pt)
{
	SendMessage(WM_LBUTTONDOWN,nFlags,MAKELONG(pt.x,pt.y));
}


void CFolderButton::OnTimer(UINT nIDEvent)
{
	if (IsWindowEnabled()) 
	{
		if (m_iState++ == 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 + -