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

📄 customtabctrl.cpp

📁 Wifi扫描器和自定义MFC控件 Wifi scanner + custom MFC controls 在WINCE环境下工作。
💻 CPP
📖 第 1 页 / 共 4 页
字号:

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

	if(GetStyle() & CTCS_BUTTONSAFTER)
	{
		rightAdjusment = nOffset;
		nOffset = 0;
	}

	for(i = 0; i<m_aItems.GetSize(); i++)
	{
		if(i < m_nFirstVisibleItem-1)
		{
			m_aItems[i]->m_bShape = TAB_INVISIBLE;
			//nOffset -= m_aItems[i]->m_rect.Width()-rCl.Height()/2;
			nOffset -= m_aItems[i]->m_rect.Width();
			m_aItems[i]->m_rectText.SetRectEmpty();
		}
		else if(i == m_nFirstVisibleItem-1)
		{
			int nBtns = 2;

			if(GetStyle() & CTCS_FOURBUTTONS)
			{
				nBtns = 4;
			}

			if(GetStyle() & CTCS_CLOSEBUTTON)
			{
				nBtns++;
			}

			int nBnWidth = nBtns*(rCl.Height() - 3) + 3;

			m_aItems[i]->m_bShape = TAB_BEFORE_FIRST_VISIBLE;

			//nOffset -= m_aItems[i]->m_rect.Width()-rCl.Height()/2;
			//no overlapping
			nOffset -= m_aItems[i]->m_rect.Width();
			
			//overlap here
			m_aItems[i]->m_rect.SetRect(0, 1, rCl.Height()/2, rCl.Height()-1);
			if(!(GetStyle() & CTCS_BUTTONSAFTER))
			{
				m_aItems[i]->m_rect.OffsetRect(nBnWidth, 0);
			}

			//this prevents some overlapping in case of no BUTTONSAFTER style
			m_aItems[i]->m_rect.SetRectEmpty();
			//text rect empty anyways
			m_aItems[i]->m_rectText.SetRectEmpty();
		}
		else
		{
			m_aItems[i]->m_bShape = TAB_VISIBLE;
			m_aItems[i]->m_rect.OffsetRect(nOffset, 0);
			m_aItems[i]->m_rectText.OffsetRect(nOffset, 0);
		}
	}//for tabs
}

//////////////////////////////////////////////////////////////////////////
//recalculate tab item rectangles (item rect and item text rect)
int CCustomTabCtrl::RecalcRectangles()
{
CRect rCl;
int i, w, h;	
BOOL fTop;
int nWidth;

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

	fTop = GetStyle()&CTCS_TOP;
	nWidth = 0;
	{
		//calculate widths
		int nOffset = 0;
		CRect rcText;
		CDC* pDC = GetDC();
		CFont* pOldFont = pDC->SelectObject(&m_FontSelected);

		if(GetStyle()&CTCS_FIXEDWIDTH)
		{
			int nMaxWidth=0;

			//get max width of items, based on item text
			for(i=0; i<m_aItems.GetSize(); i++)
			{
				w=0;
				h = pDC->DrawText(m_aItems[i]->m_sText, rcText, DT_CALCRECT);
				
				if(h>0)
				{
					w = rcText.Width();
				}
				if(w>nMaxWidth)
				{
					nMaxWidth = w;
				}
			}//for items

			for(i=0; i<m_aItems.GetSize(); i++)
			{
				if(fTop)
				{
					m_aItems[i]->m_rect = CRect(0, 0, nMaxWidth+rCl.Height()+4, rCl.bottom);
					m_aItems[i]->m_rectText = CRect(rCl.Height()/2, 0, nMaxWidth+rCl.Height()/2+4, rCl.Height()-1);
				}
				else
				{
					m_aItems[i]->m_rect = CRect(0, rCl.top, nMaxWidth+rCl.Height()+4, rCl.bottom);
					m_aItems[i]->m_rectText = CRect(rCl.Height()/2, rCl.top, nMaxWidth+rCl.Height()/2+4, rCl.bottom-1);
				}
				m_aItems[i]->m_rect += CPoint(nOffset, 0);
				m_aItems[i]->m_rectText += CPoint(nOffset, 0);

				//horizontal overlapping with height/2
				//nOffset += m_aItems[i]->m_rect.Width()-rCl.Height()/2;
				nOffset += m_aItems[i]->m_rect.Width();
				nWidth = m_aItems[i]->m_rect.right;
			}//for items
		}//if fixed width
		else
		{
			//variable width, calculate width based on individual text widths
			for(i=0; i<m_aItems.GetSize(); i++)
			{
				w=0;
				h = pDC->DrawText(m_aItems[i]->m_sText, rcText, DT_CALCRECT);
				if(h>0)
				{
					w = rcText.Width();
				}
				if(fTop)
				{
					m_aItems[i]->m_rect = CRect(0, 0, w+rCl.Height()+4, rCl.bottom);
					m_aItems[i]->m_rectText = CRect(rCl.Height()/2, 0, w+rCl.Height()/2+4, rCl.Height()-1);
				}
				else
				{
					m_aItems[i]->m_rect = CRect(0, rCl.top, w+rCl.Height()+4, rCl.bottom);
					m_aItems[i]->m_rectText = CRect(rCl.Height()/2, rCl.top, w+rCl.Height()/2+4, rCl.bottom-1);
				}
				
				m_aItems[i]->m_rect += CPoint(nOffset, 0);
				m_aItems[i]->m_rectText += CPoint(nOffset, 0);
				
				//horizontal overlapping with height/2
				//nOffset += m_aItems[i]->m_rect.Width()-rCl.Height()/2;
				nOffset += m_aItems[i]->m_rect.Width();

				nWidth = m_aItems[i]->m_rect.right;
			}//for items
		}//if not fixed width
		pDC->SelectObject(pOldFont);
		ReleaseDC(pDC);
	}

	return nWidth;
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabCtrl::DrawGlyph(CDC& dc, CPoint& pt, int nImageNdx, int nColorNdx)
{
CDC dcMem, dcMemMono;
CBitmap bmpGlyphColor;

	dcMem.CreateCompatibleDC(&dc);
	dcMemMono.CreateCompatibleDC(&dc);

	CBitmap* pOldBmpGlyphMono = dcMemMono.SelectObject(&m_bmpGlyphsMono);

	bmpGlyphColor.CreateCompatibleBitmap(&dc, 8, 7);
	
	CBitmap* pOldBmpGlyphColor = dcMem.SelectObject(&bmpGlyphColor);

	COLORREF rgbOldTextGlyph =  dcMem.SetTextColor(m_rgbGlyph[nColorNdx]);

	dcMem.BitBlt(0, 0, 8, 7, &dcMemMono, nImageNdx*8, 0, SRCCOPY);
	dcMem.SetTextColor(rgbOldTextGlyph);

	COLORREF rgbOldBk = dc.SetBkColor(RGB(255, 255, 255));
	COLORREF rgbOldText = dc.SetTextColor(RGB(0, 0, 0));

	dc.BitBlt(pt.x, pt.y, 8, 7, &dcMem, 0, 0, SRCINVERT);
	dc.BitBlt(pt.x, pt.y, 8, 7, &dcMemMono, nImageNdx*8, 0, SRCAND);
	dc.BitBlt(pt.x, pt.y, 8, 7, &dcMem, 0, 0, SRCINVERT);

	dcMem.SelectObject(pOldBmpGlyphColor);
	dcMemMono.SelectObject(pOldBmpGlyphMono);
	dc.SetBkColor(rgbOldBk);
	dc.SetTextColor(rgbOldText);
}

//////////////////////////////////////////////////////////////////////////
BOOL CCustomTabCtrl::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
int i;

	if(dwRemove & CTCS_MULTIHIGHLIGHT)
	{
		//remove highlights
		for(i=0; i<m_aItems.GetSize(); i++)
		{
			m_aItems[i]->m_fHighlighted = FALSE;
		}
	}
	if(dwAdd & CTCS_MULTIHIGHLIGHT)
	{
		//highlight all selected tabs
		for(i=0; i<m_aItems.GetSize(); i++)
		{
			if(i==m_nItemSelected)
			{
				m_aItems[i]->m_fHighlighted = TRUE;
			}
		}
	}

	//vertical styles removed
#ifdef _WIN32_WCE
	dwAdd &= ~CTCS_LEFT;
	dwAdd &= ~CTCS_RIGHT;
	CWnd::ModifyStyle(dwRemove | CTCS_LEFT | CTCS_RIGHT, dwAdd, nFlags);
#else
	CWnd::ModifyStyle(dwRemove, dwAdd, nFlags);
#endif
	RecalcLayout(RECALC_RESIZED, m_nItemSelected);
	Invalidate(FALSE);
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////
BOOL CCustomTabCtrl::ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
	CWnd::ModifyStyleEx(dwRemove, dwAdd, nFlags);
	RecalcLayout(RECALC_RESIZED, m_nItemSelected);
	Invalidate(FALSE);
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabCtrl::PreSubclassWindow() 
{
	CWnd::ModifyStyle(0, WS_CLIPCHILDREN);
	RecalcLayout(RECALC_RESIZED, m_nItemSelected);
	CWnd::PreSubclassWindow();
}

//////////////////////////////////////////////////////////////////////////
#ifndef _WIN32_WCE
void CCustomTabCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
	NotifyParent(CTCN_RCLICK, HitTest(point), point);
	CWnd::OnRButtonDown(nFlags, point);
}
#endif

//////////////////////////////////////////////////////////////////////////
#ifndef _WIN32_WCE
void CCustomTabCtrl::OnRButtonDblClk(UINT nFlags, CPoint point) 
{
	NotifyParent(CTCN_RDBLCLK, HitTest(point), point);
	CWnd::OnRButtonDblClk(nFlags, point);
}
#endif

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

//////////////////////////////////////////////////////////////////////////
int CCustomTabCtrl::EditLabel(int nItem, BOOL fMouseSel)
{
	if(nItem<0 || nItem>=m_aItems.GetSize())
	{
		return CTCERR_INDEXOUTOFRANGE;
	}
	if(!(GetStyle()&CTCS_EDITLABELS))
	{
		return CTCERR_NOEDITLABELSTYLE;
	}
	if(nItem!=m_nItemSelected)
	{
		return CTCERR_ITEMNOTSELECTED;
	}
	if(m_ctrlEdit.m_hWnd)
	{
		return CTCERR_ALREADYINEDITMODE;
	}
	if(IsVertical())
	{
		return CTCERR_EDITNOTSUPPORTED;
	}

	CRect r;
	CDC* pDC = GetDC();
	CFont* pOldFont = pDC->SelectObject(&m_FontSelected);
	int h = pDC->DrawText(m_aItems[nItem]->m_sText, 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;
	//create edit control
	if(m_ctrlEdit.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, r, this, CTCID_EDITCTRL))
	{
		CString sOld = m_aItems[nItem]->m_sText;
		m_ctrlEdit.SetFont(&m_FontSelected, FALSE);
		m_ctrlEdit.SetLimitText(MAX_LABEL_LENGTH);
		m_ctrlEdit.SetWindowText(m_aItems[nItem]->m_sText);
		m_ctrlEdit.SetFocus();
		m_ctrlEdit.SetSel(0,-1);
		if(fMouseSel)
		{
			ReleaseCapture();
		}
		//process messages in edit mode
		for(;;) 
		{
			MSG msg;
			::GetMessage(&msg, NULL, 0, 0);

			switch (msg.message) 
			{
				case WM_SYSKEYDOWN:
				{
					if(msg.wParam == VK_F4 && msg.lParam&29)
					{
						break;
					}
					TranslateMessage(&msg);
					DispatchMessage(&msg);
					break;
				}
				case WM_KEYDOWN:
				{
					if (msg.wParam == VK_ESCAPE)
					{
						m_aItems[nItem]->m_sText = sOld;
						m_ctrlEdit.DestroyWindow();
						RecalcLayout(RECALC_RESIZED,m_nItemSelected);
						Invalidate(FALSE);
						return CTCERR_NOERROR;
					}
					if(msg.wParam == VK_RETURN)
					{
						if(NotifyParent(CTCN_LABELUPDATE,nItem,CPoint(0,0)))
							break;
						m_ctrlEdit.GetWindowText(m_aItems[nItem]->m_sText);
						m_ctrlEdit.DestroyWindow();
						RecalcLayout(RECALC_RESIZED,nItem);
						Invalidate(FALSE);
						return CTCERR_NOERROR;
					}
					TranslateMessage(&msg);
					DispatchMessage(&msg);
					break;
				}
				case WM_LBUTTONDOWN:
				{
					if(msg.hwnd == m_hWnd)
					{
						POINTS pt = MAKEPOINTS(msg.lParam);
						if(HitTest(CPoint(pt.x, pt.y)) != m_nItemSelected)
						{
							if(NotifyParent(CTCN_LABELUPDATE, nItem, CPoint(0, 0)))
							{
								break;
							}
							m_ctrlEdit.GetWindowText(m_aItems[m_nItemSelected]->m_sText);
							m_ctrlEdit.DestroyWindow();
							TranslateMessage(&msg);
							DispatchMessage(&msg);
							return CTCERR_NOERROR;
						}
					}
					else if(msg.hwnd == m_ctrlEdit.m_hWnd)
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					else
					{
						if(NotifyParent(CTCN_LABELUPDATE, nItem, CPoint(0, 0)))
						{
							break;
						}
						m_ctrlEdit.GetWindowText(m_aItems[m_nItemSelected]->m_sText);
						m_ctrlEdit.DestroyWindow();
						return CTCERR_NOERROR;
					}
					break;
				}
				case WM_LBUTTONUP:
				{
					if(msg.hwnd==m_ctrlEdit.m_hWnd)
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					break;
				}
				case WM_LBUTTONDBLCLK:
#ifndef _WIN32_WCE
				case WM_RBUTTONDOWN:
				case WM_RBUTTONUP:
#endif
				{
					break;
				}				
				default:
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
					break;
				}
			}//switch message
		}//for(ever)
	}//if edit control created
	return CTCERR_NOERROR;
}

//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CCustomTabContainer, CCustomTabCtrl)

CCustomTabContainer::CCustomTabContainer()
{
}

//////////////////////////////////////////////////////////////////////////
CCustomTabContainer::~CCustomTabContainer()
{
int i;

	for(i=0; i<m_Dlgs.GetSize(); i++)
	{
		delete m_Dlgs[i];
	}
	m_Dlgs.RemoveAll();
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::FixStyle(HWND hWnd)
{
LONG lStyle;

	lStyle=GetWindowLong(hWnd, GWL_STYLE);
	lStyle &= ~WS_CAPTION;
	lStyle &= ~DS_MODALFRAME;
	lStyle &= ~WS_POPUP;
	lStyle |= WS_CHILD;
	SetWindowLong(hWnd, GWL_STYLE, lStyle);
}

BEGIN_MESSAGE_MAP(CCustomTabContainer, CCustomTabCtrl)
	//{{AFX_MSG_MAP(MyTabCtrl)
	ON_NOTIFY_REFLECT(CTCN_SELCHANGE, OnSelchange)
	ON_NOTIFY_REFLECT(CTCN_CLICK, OnTabBtnClick)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// MyTabCtrl message handlers

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) 
{
	Display();
	*pResult = 0;
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::OnTabBtnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
CTC_NMHDR *pCHdr;

	pCHdr=(CTC_NMHDR *)pNMHDR;
	if(pCHdr->nItem == CTCID_CLOSEBUTTON)
	{
		//close
		RemoveDialog(GetCurSel());		
	}
	Display();
	*pResult = 0;
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::AddDialog(int nIndex, CString strText, CDialog *pDlg)
{
	FixStyle(pDlg->GetSafeHwnd());

	m_Dlgs.InsertAt(nIndex, pDlg);
	if(strText != _T(""))
	{
		InsertItem(nIndex, strText);
	}
	else
	{
		InsertItem(nIndex, _T("<No title>"));
	}

	//nothing yet selected?
	if(GetCurSel() < 0)
	{
		//select once
		SetCurSel(nIndex);
		Display();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::RemoveDialog(int nIndex)
{
	if(nIndex >= 0 && nIndex < GetItemCount())
	{
		DeleteItem(nIndex);
		delete m_Dlgs[nIndex];
		m_Dlgs.RemoveAt(nIndex);
		Display();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCustomTabContainer::Display()
{
int i, nSel;
CRect rcClient, rcWnd;

	GetClientRect(rcClient);
	GetWindowRect(rcWnd);

	AdjustRect(FALSE, rcClient);

	//no dialogs? then wipe background
	if(m_Dlgs.GetCount() == 0)
	{
		CDC *pDC=GetDC();
		if(pDC != NULL)
		{
			pDC->FillSolidRect(rcClient, m_ticColors.crWndBkg);		
			ReleaseDC(pDC);
		}
	}

	nSel=GetCurSel();
	if(nSel < 0 || nSel >= GetItemCount())
	{
		return;
	}

	if(m_Dlgs[nSel]->m_hWnd)
	{
		m_Dlgs[nSel]->ShowWindow(SW_HIDE);
	}

	GetParent()->ScreenToClient(rcWnd);

	rcClient.OffsetRect(rcWnd.left, rcWnd.top);

	for(i=0; i < m_Dlgs.GetCount(); i++)
	{
		m_Dlgs[i]->SetWindowPos(&wndTop, rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), SWP_HIDEWINDOW);
	}
	m_Dlgs[nSel]->SetWindowPos(&wndTop, rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), SWP_SHOWWINDOW);
	m_Dlgs[nSel]->ShowWindow(SW_SHOW);

	if(GetStyle() & CTCS_NOLINES)
	{
		return;
	}

	//once displayed, draw a line around dialog display area
/*
	GetClientRect(rcClient);
	AdjustRect(FALSE, rcClient);

	CDC *pDC=GetDC();
	if(pDC != NULL)
	{
		CPen pen(PS_SOLID, 1, m_ticColors.crDarkLine);
		HGDIOBJ hOldPen;

		hOldPen=pDC->SelectObject(pen);
		if(GetStyle() & CTCS_TOP)
		{
			pDC->MoveTo(0, rcClient.top);
			pDC->LineTo(0, rcClient.bottom);
			pDC->LineTo(rcClient.right-1, rcClient.bottom);
			pDC->LineTo(rcClient.right-1, rcClient.top);
		}
		else
		{
			pDC->MoveTo(0, rcClient.bottom);
			pDC->LineTo(0, rcClient.top);
			pDC->LineTo(rcClient.right-1, rcClient.top);
			pDC->LineTo(rcClient.right-1, rcClient.bottom);
		}
		pDC->SelectObject(hOldPen);
		ReleaseDC(pDC);
	}
*/
}

⌨️ 快捷键说明

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