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

📄 customtabctrl.cpp

📁 Wifi扫描器和自定义MFC控件 Wifi scanner + custom MFC controls 在WINCE环境下工作。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}
	}
	int ndx = 1;
	while(1)
	{
		ndx++;
		if(bAppendFlag)
		{
			sDst.Format(_T("%s (%d)"), (LPCTSTR)m_aItems[nItemSrc]->m_sText, ndx);
		}
		else
		{
			sDst.Format(_T("%s(%d)"), (LPCTSTR)m_aItems[nItemSrc]->m_sText.Left(n), ndx);
		}
		for(i=0; i<m_aItems.GetSize(); i++)
		{
			if(m_aItems[i]->m_sText==sDst)
			{
				break;
			}
		}
		if(i == m_aItems.GetSize())
		{
			break;
		}
	}

	int nRetItem = InsertItem(nItemDst,sDst,m_aItems[nItemSrc]->m_lParam);
	if(nRetItem>=0)
	{
		SetCurSel(nRetItem);
		if(fMouseSel)
		{
			NotifyParent(CTCN_ITEMCOPY, nRetItem, CPoint(0, 0));
		}
	}
	else if(fMouseSel && nRetItem==CTCERR_OUTOFMEMORY)
	{
		NotifyParent(CTCN_OUTOFMEMORY, nRetItem, CPoint(0, 0));
	}

	return nRetItem;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::DeleteItem(int nItem)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}

	if(m_aItems.GetSize()==1)
	{
		m_nItemSelected = -1;
	}
	else if(m_nItemSelected==nItem)
	{
		if(m_nItemSelected==m_aItems.GetSize()-1) // last item
		{
			m_nItemSelected--;
			m_aItems[m_nItemSelected]->m_fSelected = TRUE;	
		}
		else
		{
			m_aItems[m_nItemSelected+1]->m_fSelected = TRUE;	
		}
	}
	else if(m_nItemSelected>nItem)
	{
		m_nItemSelected--;
	}

	delete m_aItems[nItem];
	m_aItems.RemoveAt(nItem);

	RecalcLayout(RECALC_RESIZED, m_nItemSelected);
	Invalidate(FALSE);
	return CTCERR_NOERROR;
}

void CCustomTabCtrl::DeleteAllItems()
{
	{
		for(int i=0; i< m_aItems.GetSize(); i++)
			delete m_aItems[i];
	}

	m_aItems.RemoveAll();

	m_nItemSelected = -1;
		
	RecalcLayout(RECALC_RESIZED,m_nItemSelected);
	Invalidate(FALSE);
}

int CCustomTabCtrl::SetCurSel(int nItem)
{
	return SetCurSel(nItem,FALSE,FALSE);
}

int CCustomTabCtrl::HighlightItem(int nItem, BOOL fHighlight)
{
	if(!(GetStyle()&CTCS_MULTIHIGHLIGHT))
		return CTCERR_NOMULTIHIGHLIGHTSTYLE;
	if(nItem<0 || nItem>=m_aItems.GetSize())
		return CTCERR_INDEXOUTOFRANGE;
	if(m_nItemSelected==-1 && !fHighlight)
		return CTCERR_NOERROR;
	if(m_nItemSelected==-1)
	{
		SetCurSel(nItem);
		return CTCERR_NOERROR;
	}
	if(fHighlight==m_aItems[nItem]->m_fHighlighted || nItem==m_nItemSelected)
		return CTCERR_NOERROR;
	
	m_aItems[nItem]->m_fHighlighted = fHighlight;
	return CTCERR_NOERROR;
}

int CCustomTabCtrl::GetItemText(int nItem, CString& sText)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
		return CTCERR_INDEXOUTOFRANGE;
	sText = m_aItems[nItem]->m_sText;
	return CTCERR_NOERROR;
}

int CCustomTabCtrl::SetItemText(int nItem, CString sText)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
		return CTCERR_INDEXOUTOFRANGE;
	m_aItems[nItem]->m_sText = sText;
	RecalcLayout(RECALC_RESIZED,m_nItemSelected);
	Invalidate(FALSE);
	return CTCERR_NOERROR;
}


int CCustomTabCtrl::GetItemData(int nItem, DWORD& dwData)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}
	dwData = (DWORD)m_aItems[nItem]->m_lParam;
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::GetItemRect(int nItem, CRect& rect) const
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}
	rect = m_aItems[nItem]->m_rectText;
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::SetItemData(int nItem, DWORD dwData)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}
	m_aItems[nItem]->m_lParam = dwData;
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::IsItemHighlighted(int nItem)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}
	return (m_aItems[nItem]->m_fHighlighted)?1:0;
}

//////////////////////////////////////////////////////////////////////////
int	CCustomTabCtrl::HitTest(CPoint pt)
{
CRect rCl;
int i, nBtns;

	GetTabsRect(&rCl);
	if(IsVertical())
	{
		rCl.SetRect(0, 0, rCl.Height(), rCl.Width());
		pt = CPoint(rCl.Width()-pt.y, pt.x);
	}

	nBtns = 0;
	if(m_nCloseState)
	{
		nBtns++;
	}
	if(m_nPrevState)
	{
		nBtns += 2;
	}
	if(m_nFirstState)
	{
		nBtns += 2;
	}
	int nA = rCl.Height()-2;

	int nCloseOffset = 0;
	if(m_nCloseState)
	{
		nCloseOffset = nA;
		CRect rClose(0, rCl.top, nA+1, rCl.bottom);
		if(GetStyle()&CTCS_BUTTONSAFTER)
		{
			rClose.SetRect(rCl.Width()-nA-1, rCl.top, rCl.Width(), rCl.bottom);
		}
		if(rClose.PtInRect(pt))
		{
			return CTCHT_ONCLOSEBUTTON;
		}
	}

	CRect rFirst, rPrev, rNext, rLast;

	if(GetStyle()&CTCS_BUTTONSAFTER)
	{
		if(nBtns==2 || nBtns==3)
		{
			rNext.SetRect(rCl.Width()-nCloseOffset-nA-1, rCl.top, rCl.Width()-nCloseOffset, rCl.bottom);
			rPrev.SetRect(rCl.Width()-nCloseOffset-2*nA-3, rCl.top, rCl.Width()-nCloseOffset-nA-1, rCl.bottom);
		}
		else if(nBtns==4 || nBtns==5)
		{
			rLast.SetRect(rCl.Width()-nCloseOffset-nA-1, rCl.top, rCl.Width()-nCloseOffset, rCl.bottom);
			rNext.SetRect(rCl.Width()-nCloseOffset-2*nA-1, rCl.top, rCl.Width()-nCloseOffset-nA-1, rCl.bottom);
			rPrev.SetRect(rCl.Width()-nCloseOffset-3*nA-2, rCl.top, rCl.Width()-nCloseOffset-2*nA-1, rCl.bottom);
			rFirst.SetRect(rCl.Width()-nCloseOffset-4*nA-3, rCl.top, rCl.Width()-nCloseOffset-3*nA-2, rCl.bottom);
		}
	}
	else
	{
		if(nBtns==2 || nBtns==3)
		{
			rPrev.SetRect(nCloseOffset, rCl.top, nCloseOffset+nA+1, rCl.bottom);
			rNext.SetRect(nCloseOffset+nA+1, rCl.top, nCloseOffset+2*nA+3, rCl.bottom);
		}
		else if(nBtns==4 || nBtns==5)
		{
			rFirst.SetRect(nCloseOffset, rCl.top, nCloseOffset+nA+1, rCl.bottom);
			rPrev.SetRect(nCloseOffset+nA+1, rCl.top, nCloseOffset+2*nA+1, rCl.bottom);
			rNext.SetRect(nCloseOffset+2*nA+1, rCl.top, nCloseOffset+3*nA+2, rCl.bottom);
			rLast.SetRect(nCloseOffset+3*nA+2, rCl.top, nCloseOffset+4*nA+3, rCl.bottom);
		}
	}

	if(nBtns>=4 && m_nFirstState && rFirst.PtInRect(pt))
	{
		return CTCHT_ONFIRSTBUTTON;
	}

	if(m_nPrevState && rPrev.PtInRect(pt))
	{
		return CTCHT_ONPREVBUTTON;
	}
	
	if(m_nNextState && rNext.PtInRect(pt))
	{
		return CTCHT_ONNEXTBUTTON;
	}
	
	if(nBtns>=4 && m_nLastState && rLast.PtInRect(pt))
	{
		return CTCHT_ONLASTBUTTON;
	}

	for(i=0; i<m_aItems.GetSize(); i++)
	{
		if(m_aItems[i]->HitTest(pt))
		{
			return i;
		}
	}
	return CTCHT_NOWHERE;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::HighlightItem(int nItem, BOOL fMouseSel, BOOL fCtrlPressed)
{
int i;

	if(!(GetStyle()&CTCS_MULTIHIGHLIGHT))
	{
		return CTCERR_NOMULTIHIGHLIGHTSTYLE;
	}

	for(i=0; i<m_aItems.GetSize();i++)
	{
		m_aItems[i]->m_fHighlightChanged = FALSE;
	}

	if(fCtrlPressed)
	{
		if(nItem!=m_nItemSelected)
		{
			m_aItems[nItem]->m_fHighlighted = !m_aItems[nItem]->m_fHighlighted;
			if(fMouseSel)
			{
				m_aItems[nItem]->m_fHighlightChanged = TRUE;
			}
		}
	}
	else
	if(!m_aItems[nItem]->m_fHighlighted)
	{
		m_aItems[nItem]->m_fHighlighted = TRUE;
		m_aItems[nItem]->m_fHighlightChanged = TRUE;
		for(i=0; i<m_aItems.GetSize(); i++)
		{
			if(i!=m_nItemSelected)
			{
				if(m_aItems[i]->m_fHighlighted)
				{
					m_aItems[i]->m_fHighlighted = FALSE;
					if(fMouseSel)
					{
						m_aItems[i]->m_fHighlightChanged = TRUE;
					}
				}
			}
		}//for items
	}

	if(fMouseSel)
	{
		RecalcLayout(RECALC_ITEM_SELECTED,nItem);
	}
	Invalidate(FALSE);
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::SetCurSel(int nItem, BOOL fMouseSel, BOOL fCtrlPressed)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}

	if(m_nItemSelected!=-1)
	{
		m_aItems[m_nItemSelected]->m_fSelected = FALSE;
	}

	m_nItemSelected = nItem;
	
	if(m_nItemSelected!=-1)
	{
		m_aItems[m_nItemSelected]->m_fSelected = TRUE;
	}

	if(fMouseSel)
	{
		RecalcLayout(RECALC_ITEM_SELECTED, m_nItemSelected);
	}
	else
	{
		m_nFirstVisibleItem = nItem;
		RecalcLayout(RECALC_RESIZED, m_nItemSelected);
	}
	Invalidate(FALSE);
	HighlightItem(nItem, fMouseSel, fCtrlPressed);
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabCtrl::RecalcLayout(int nRecalcType, int nItem)
{
CRect rCl;
int nCloseOffset, nA, nBnWidth, nBtns;

	GetTabsRect(&rCl);

	if(IsVertical())
	{
		rCl.SetRect(0, 0, rCl.Height(), rCl.Width());
	}

	nCloseOffset = 0;
	nA = rCl.Height()-3;
	nBnWidth = 0;
	nBtns = 0;

	if(GetStyle()&CTCS_CLOSEBUTTON)
	{
		nBtns++;
		nCloseOffset = nA;
		nBnWidth = nA+3;
		//show close button
		if(m_nCloseState == BNST_INVISIBLE)
		{
			m_nCloseState = BNST_NORMAL;
		}
	}
	else
	{
		m_nCloseState = BNST_INVISIBLE;
	}

	int nWidth = RecalcRectangles();

	if((GetStyle()&CTCS_AUTOHIDEBUTTONS) && (m_aItems.GetSize()<2 || nWidth <= rCl.Width()-nBnWidth))
	{
		//hide buttons
		m_nFirstState = BNST_INVISIBLE;
		m_nPrevState = BNST_INVISIBLE;
		m_nNextState = BNST_INVISIBLE;
		m_nLastState = BNST_INVISIBLE;
		m_nFirstVisibleItem = 0;

		RecalcOffset(nBnWidth);
		if(nRecalcType == RECALC_EDIT_RESIZED)
		{
			RecalcEditResized(0, nItem);
		}
		return;
	}
	
	if(m_nPrevState==BNST_INVISIBLE)
	{
		m_nPrevState = BNST_NORMAL;
		m_nNextState = BNST_NORMAL;
	}

	if(GetStyle()&CTCS_FOURBUTTONS)
	{
		nBtns += 4;
		if(m_nFirstState==BNST_INVISIBLE)
		{
			m_nFirstState = BNST_NORMAL;
			m_nLastState = BNST_NORMAL;
		}
	}
	else
	{
		nBtns += 2;
		m_nFirstState = BNST_INVISIBLE;
		m_nLastState = BNST_INVISIBLE;
	}
		
	if(m_aItems.GetSize()==0)
	{
		return;
	}
	
	nBnWidth = nBtns*nA+3;	
	if(GetStyle()&CTCS_BUTTONSAFTER)
	{
		rCl.right -= nBnWidth;
	}

	switch(nRecalcType)
	{
		case RECALC_CLOSE_PRESSED:
		{
			RecalcRectangles();
			RecalcOffset(nBnWidth);
			break;
		}
		case RECALC_FIRST_PRESSED:
		{
			m_nFirstVisibleItem=0;
			RecalcRectangles();
			RecalcOffset(nBnWidth);
			break;
		}
		case RECALC_PREV_PRESSED:
		{	
			RecalcOffset(nBnWidth);
			if(m_nFirstVisibleItem > 0)
			{
				m_nFirstVisibleItem--;
				RecalcRectangles();
				RecalcOffset(nBnWidth);
			}
			break;
		}
		case RECALC_NEXT_PRESSED:
		{	
			RecalcOffset(nBnWidth);
			if(m_aItems[m_aItems.GetSize()-1]->m_rect.right > rCl.Width() && m_nFirstVisibleItem != m_aItems.GetSize()-1)
			{
				m_nFirstVisibleItem++;
				RecalcRectangles();
				RecalcOffset(nBnWidth);
			}
			break;
		}
		case RECALC_ITEM_SELECTED:
		{
			RecalcOffset(nBnWidth);
			if(m_aItems[nItem]->m_bShape==TAB_BEFORE_FIRST_VISIBLE)
			{
				m_nFirstVisibleItem--;
				RecalcRectangles();
				RecalcOffset(nBnWidth);
			}
			else
			{
				while(m_nFirstVisibleItem < nItem && 
						m_aItems[nItem]->m_bShape==TAB_VISIBLE && 
						m_aItems[nItem]->m_rect.right > rCl.Width() && 
						m_aItems[nItem]->m_rect.left > ((GetStyle()&CTCS_BUTTONSAFTER)? 0:nBnWidth))
				{
					m_nFirstVisibleItem++;
					RecalcRectangles();
					RecalcOffset(nBnWidth);
				}
			}
			break;
		}
		case RECALC_EDIT_RESIZED:
		{
			RecalcOffset(nBnWidth);
			RecalcEditResized(nBnWidth,nItem);
			break;
		}
		case RECALC_LAST_PRESSED:
		{
			m_nFirstVisibleItem=(int)m_aItems.GetSize()-1;

			//no break here?
		}
		default:	// window resized
		{
			BOOL bNdxOffsetChanged = FALSE;
			RecalcOffset(nBnWidth);
			while(m_nFirstVisibleItem>=0 && m_aItems[m_aItems.GetSize()-1]->m_rect.right < rCl.Width())
			{
				m_nFirstVisibleItem--;
				if(m_nFirstVisibleItem>=0)
				{
					RecalcRectangles();
					RecalcOffset(nBnWidth);
				}
				bNdxOffsetChanged = TRUE;
			}
			if(bNdxOffsetChanged)
			{
				m_nFirstVisibleItem++;
				RecalcRectangles();
				RecalcOffset(nBnWidth);
			}
			break;
		}//default
	}//switch recalc type
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabCtrl::RecalcEditResized(int nOffset, int nItem)
{
CRect rCl;

	GetTabsRect(rCl);

	if(GetStyle() & CTCS_BUTTONSAFTER)
	{
		rCl.right -= nOffset;
	}

	do
	{
		CRect r;
		CDC* pDC = GetDC();
		CFont* pOldFont = pDC->SelectObject(&m_FontSelected);
		int h = pDC->DrawText(m_aItems[nItem]->m_sText+_T("X"), r, DT_CALCRECT);
		pDC->SelectObject(pOldFont);
		ReleaseDC(pDC);
		r = m_aItems[nItem]->m_rectText;
		if(r.Height()>h)
		{
			r.top += (r.Height()-h)/2;
			r.bottom -= (r.Height()-h)/2;
		}
		r.left += 2;
		if(r.right>rCl.right && m_nItemSelected>m_nFirstVisibleItem)
		{
			m_nFirstVisibleItem++;
			RecalcRectangles();
			RecalcOffset(nOffset);
		}
		else
		{
			if(r.right>rCl.right)
			{
				r.right = rCl.right;
			}
			m_ctrlEdit.MoveWindow(r);
			int n = m_aItems[nItem]->m_sText.GetLength();
			int nStart, nEnd;
			m_ctrlEdit.GetSel(nStart, nEnd);
			if(nStart == nEnd && nStart == n)
			{
				m_ctrlEdit.SetSel(0, 0);
				m_ctrlEdit.SetSel(n, n);
			}
			return;
		}
	} 
	while(1);
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabCtrl::RecalcOffset(int nOffset)
{
CRect rCl;
int i;

	GetTabsRect(&rCl);

⌨️ 快捷键说明

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