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

📄 tabctrl.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:

		m_bLockRefreshBandInfo = false;
		RefreshBandInfo();

		return true;
	}

//	bool SetItem(int nIndex, const CTabCtrlItem& item)
//	{
//		if (!_IsValidIndex(nIndex))
//			return false;

//		m_items[nIndex] = item;
//		_UpdateItems(nIndex);
//	}

	bool SetItemText(int nIndex, const CString& str)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].m_strItem == str)
			return true;


		m_items[nIndex].m_strItem = str;
			
		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
			InvalidateRect(m_items[nIndex].m_rcItem);
			UpdateWindow();
		}
		else {
			InvalidateRect(m_items[nIndex].m_rcItem);// even if layout will not be changed
			_UpdateLayout();//_UpdateItems(nIndex);
		}

		return true;
	}

	bool SetItemImageIndex(int nIndex, int nImgIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].m_nImgIndex == nImgIndex)
			return true;

		m_items[nIndex].m_nImgIndex = nImgIndex;

		// imagelist does'nt change item rect
//		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
			InvalidateRect(m_items[nIndex].m_rcItem);
			UpdateWindow();
//		}
//		else {
//			InvalidateRect(m_items[nIndex].m_rcItem);// even if layout will not be changed
//			_UpdateLayout();//_UpdateItems(nIndex);
//		}

		return true;
	}

	bool SetItemInactive(int nIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].ModifyState(0, TCISTATE_INACTIVE)) {
			InvalidateRect(m_items[nIndex].m_rcItem, FALSE);
			return true;
		}

		return false;
	}

	bool SetItemActive(int nIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].ModifyState(TCISTATE_INACTIVE, 0)) {
			InvalidateRect(m_items[nIndex].m_rcItem, FALSE);
			return true;
		}

		return false;
	}


	bool SetItemDisabled(int nIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].ModifyState(TCISTATE_ENABLED, 0)) {
			InvalidateRect(m_items[nIndex].m_rcItem);
			return true;
		}

		return false;
	}

	bool SetItemEnabled(int nIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (m_items[nIndex].ModifyState(0, TCISTATE_ENABLED)) {
			InvalidateRect(m_items[nIndex].m_rcItem);
			return true;
		}

		return false;
	}


	bool SetItemUserData(int nIndex, DWORD dwUser)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		m_items[nIndex].m_dwUser = m_dwUser;
		return true;
	}

	bool GetItem(int nIndex, CTabCtrlItem& item)
	{
		if (!_IsValidIndex(nIndex))
			return false;
		
		item = m_items[nIndex];
		return true;
	}

	bool GetItemText(int nIndex, CString& str)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		str = m_items[nIndex].m_strItem;
		return true;
	}

	bool GetItemImageIndex(int nIndex, int& nImgIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		nImgIndex = m_items[nIndex].m_nImgIndex;
		return true;
	}

	bool GetItemUserData(int nIndex, DWORD& dwData)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		dwData = m_items[nIndex].m_dwUser;
		return true;
	}

	bool GetItemRect(int nIndex, CRect& rc)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		if (!(m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE) && nIndex < m_nFirstIndexOnSingleLine)
			return false;

		rc = m_items[nIndex].m_rcItem;
		return true;
	}

	bool AddItem(const CTabCtrlItem& item)
	{
		_HotItem();

		m_items.push_back(item);
		_UpdateLayout();// _UpdateItems(m_items.size() - 1);
		return true;
	}

	bool DeleteItem(int nIndex)
	{
		if (!_IsValidIndex(nIndex))
			return false;

		_HotItem();

		// first, post it
		InvalidateRect(_InflateGapWidth(m_items[nIndex].m_rcItem));
//		_InvalidateItemsRect(nIndex, m_items.size());

		if (nIndex < m_nFirstIndexOnSingleLine || nIndex + 1 == GetItemCount()) {
			--m_nFirstIndexOnSingleLine;
			if (m_nFirstIndexOnSingleLine < 0)
				m_nFirstIndexOnSingleLine = 0;
		}

		m_items.erase(m_items.begin() + nIndex);
		_UpdateLayout();
		return true;
	}

	void GetCurMultiSel(CSimpleArray<int>& arrDest, bool bIncludeCurSel = true)
	{// have to be sorted!
		arrDest.RemoveAll();

		for (int i = 0; i < m_items.size(); ++i) {
			if (bIncludeCurSel) {
				if (m_items[i].m_fsState & TCISTATE_SELECTED) {
					arrDest.Add(i);
					continue;
				}
			}

			if (m_items[i].m_fsState & TCISTATE_MSELECTED)
				arrDest.Add(i);
		}
	}

	bool SetCurSel(int nIndex, bool bClicked = false)
	{
		TCTRACE(_T("SetCurSel\n"));
		if (!_IsValidIndex(nIndex)) {
			TCTRACE(_T(" invalid index\n"));
			return false;
		}

		_ResetMultiSelectedItems();
		int nCurSel = GetCurSel();

		if (nCurSel != -1 && nCurSel == nIndex) {
			TCTRACE(_T(" no need\n"));
			return true;
		}

		// clean up
		if (_IsValidIndex(nCurSel)) {
			if (m_items[nCurSel].ModifyState(TCISTATE_SELECTED | TCISTATE_HOT | TCISTATE_PRESSED | TCISTATE_MSELECTED, 0))
				InvalidateRect(m_items[nCurSel].m_rcItem);
		}

		// new selected item
		if (m_items[nIndex].ModifyState(TCISTATE_HOT | TCISTATE_PRESSED | TCISTATE_MSELECTED, TCISTATE_SELECTED))
			InvalidateRect(m_items[nIndex].m_rcItem);

		_ScrollOpposite(nIndex, bClicked);

		T* pT = static_cast<T*>(this);
		pT->OnSetCurSel(nIndex);

		UpdateWindow();
		return true;
	}

	void _ScrollOpposite(int nNewSel, bool bClicked)
	{
		ATLASSERT(_IsValidIndex(nNewSel));

		if (GetItemCount() < 2)
			return;

		if (!(m_dwTabCtrl2ExtendedStyle & TAB2_EX_SCROLLOPPOSITE))
			return;

		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
			return;

		if (!m_wndUpDown.IsWindowVisible())
			return;

		const CRect& rcItem = m_items[nNewSel].m_rcItem;

		CRect rcClient; GetClientRect(rcClient);

		if (bClicked) {
			if (m_nFirstIndexOnSingleLine != nNewSel) {
				CRect rcUpDown; m_wndUpDown.GetWindowRect(rcUpDown);
				ScreenToClient(rcUpDown);

				if (MtlIsCrossRect(rcItem, rcUpDown))
					ScrollItem();				
			}
		}
		else if (rcItem.IsRectEmpty() || (rcClient & rcItem) != rcItem) {// outside or crossed
			m_nFirstIndexOnSingleLine = MtlMax(0, nNewSel - 1);//nNewSel;
			_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
			Invalidate();
			_ShowOrHideUpDownCtrl(rcClient);
		}
	}

	void RefreshBandInfo()
	{
		ATLASSERT(m_dwTabCtrl2ExtendedStyle & TAB2_EX_SUPPORTREBAR);

		if (m_bLockRefreshBandInfo)
			return;

		HWND hWndReBar = GetParent();
		CReBarCtrl rebar(hWndReBar);
		REBARBANDINFO rbBand;
		rbBand.cbSize = sizeof(REBARBANDINFO);
		rbBand.fMask = RBBIM_CHILDSIZE;

		int nIndex = rebar.IdToIndex(GetDlgCtrlID());
		rebar.GetBandInfo(nIndex, &rbBand);
		if (rbBand.cyMinChild != _GetRequiredHeight()) {
			// Calculate the size of the band
			rbBand.cxMinChild = 0;
			rbBand.cyMinChild = _GetRequiredHeight();

			rebar.SetBandInfo(nIndex, &rbBand);
		}
	}

	int GetItemHeight()
	{
		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_FIXEDSIZE) {
			return m_sizeItem.cy;
		}
		else {
			int cxIcon = 0, cyIcon = 0;
			if (m_imgs.m_hImageList != NULL)
				m_imgs.GetIconSize(cxIcon, cyIcon);

			LOGFONT lf;
			m_font.GetLogFont(lf);
			int cy = lf.lfHeight;
			if(cy < 0)
				cy = -cy;
			cy += 2 * s_kcyTextMargin;

			return MtlMax(cy, cxIcon);
		}
	}

	bool CanScrollItem(bool bRight = true)
	{
		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
			return false;// can't

		if (bRight) {
			if (m_nFirstIndexOnSingleLine + 1 < GetItemCount()) {
				return true;
			}
			else {
				return false;
			}
		}
		else {
			if (m_nFirstIndexOnSingleLine - 1 >= 0) {
				return true;
			}
			else {
				return false;
			}
		}
	}

	bool ScrollItem(bool bRight = true)
	{
		if (m_dwTabCtrl2ExtendedStyle & TAB2_EX_MULTILINE)
			return false;// do nothing

		if (bRight) {
			if (m_nFirstIndexOnSingleLine + 1 < GetItemCount()) {
				++m_nFirstIndexOnSingleLine;
				_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
				Invalidate();
			}
			else {
				return false;
			}
		}
		else {
			if (m_nFirstIndexOnSingleLine - 1 >= 0) {
				--m_nFirstIndexOnSingleLine;
				_UpdateSingleLineLayout(m_nFirstIndexOnSingleLine);
				Invalidate();
			}
			else {
				return false;
			}
		}

		CRect rcClient; GetClientRect(&rcClient);
		_ShowOrHideUpDownCtrl(rcClient);
		return true;
	}

// Overrides
	void OnTrackMouseMove(UINT nFlags, CPoint pt)
	{
		int nIndex = HitTest(pt);
		if (_IsValidIndex(nIndex)) {
			if (m_nHotIndex == -1 || m_nHotIndex != nIndex) {	// if other button made hot or first hot
				m_tip.Activate(FALSE);
				m_tip.Activate(TRUE);
				PostMessage(WM_MOUSEMOVE, (WPARAM)nFlags, MAKELPARAM(pt.x, pt.y));// make sure

				_HotItem(nIndex);// button made hot with mouse
			}
		}
		else {
			m_tip.Activate(FALSE);
			_HotItem();
		}
	}

	void OnTrackMouseLeave()
	{
		m_tip.SetDelayTime(TTDT_INITIAL, 500);
		_HotItem();
	}

// Message map and handlers
	BEGIN_MSG_MAP(CTabCtrl2Impl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		NOTIFY_CODE_HANDLER(UDN_DELTAPOS, OnDeltaPos)
		NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnGetDispInfo)
		CHAIN_MSG_MAP(CTrackMouseLeave<CTabCtrl2Impl>)
	END_MSG_MAP()

	LRESULT OnDeltaPos(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
	{
		LPNMUPDOWN lpnmud = (LPNMUPDOWN)pnmh;
		TCTRACE(_T("OnDeltaPos iPos(%d), iDelta(%d)\n"), lpnmud->iPos, lpnmud->iDelta);
		ScrollItem(lpnmud->iDelta > 0);

		return 0;
	}

	LRESULT OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
	{
		LPNMTTDISPINFO pDispInfo = (LPNMTTDISPINFO)pnmh;
		TCTRACE(_T("OnGetDispInfo\n"));
		CPoint ptCursor; ::GetCursorPos(&ptCursor);
		ScreenToClient(&ptCursor);
		int nIndex = HitTest(ptCursor);
		if (_IsValidIndex(nIndex)) {
			T* pT = static_cast<T*>(this);
			CString strToolTip = pT->OnGetToolTipText(nIndex);
			strToolTip = MtlCompactString(strToolTip, _countof(pDispInfo->szText));
			::lstrcpyn(pDispInfo->szText, strToolTip, _countof(pDispInfo->szText));
		}
		else {
			pDispInfo->szText[0] = _T('\0');
		}

		m_tip.SetDelayTime(TTDT_INITIAL, m_tip.GetDelayTime(TTDT_RESHOW));

		return 0;
	}

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// maybe nothing done
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
		// get and use system settings
		GetSystemSettings();
		
		m_wndUpDown.Create(m_hWnd, CRect(0, 0, s_kcxUpDown, s_kcyUpDown), NULL, WS_CHILD|WS_OVERLAPPED|UDS_HORZ);
		_InitToolTip();

		// default size
		MoveWindow(0, 0, 200, _GetRequiredHeight(), FALSE);
		return lRet;
	}

	LRESULT OnWindowPosChanging(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = FALSE;
		LPWINDOWPOS lpwndpos = (LPWINDOWPOS)lParam;

⌨️ 快捷键说明

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