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

📄 xlistctrl.cpp

📁 一个类似于CListCtrl的控件类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x+k, y);
			x++;
			y++;
			k -= 2;
		}
	}
	else
	{
		// draw normal combobox
		m_rectComboButton = ArrowRect;
		CBrush brush(m_cr3DShadow);
		pDC->FrameRect(&ArrowRect, &brush);
		ArrowRect.DeflateRect(1, 1);
		pDC->FillSolidRect(ArrowRect, m_crBtnFace);

		// draw the downarrow using blackpen
		int x = ArrowRect.left + 3;
		int y = ArrowRect.top + 4;
		int k = 5;
		for (int i = 0; i < 3; i++)
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x+k, y);
			x++;
			y++;
			k -= 2;
		}

		// show listbox if not already shown
		if (!m_pListBox)
		{
			// create and populate the combo's listbox
			m_pListBox = new CXComboList(this);
			ASSERT(m_pListBox);

			if (m_pListBox)
			{
				m_nComboItem = nItem;
				m_nComboSubItem = nSubItem;

				m_rectComboList = rect;
				m_rectComboList.right -= 1;
				m_rectComboList.top += rect.Height() - 1;

				m_rectComboList.bottom = m_rectComboList.top +
					(pXLCD[nSubItem].nComboListHeight) * (rect.Height() - 2);
				ClientToScreen(&m_rectComboList);

				CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS,
														  LoadCursor(NULL, IDC_ARROW));

				BOOL bSuccess = m_pListBox->CreateEx(0, szClassName, _T(""),
									WS_POPUP | WS_VISIBLE /*| WS_VSCROLL*/ | WS_BORDER,
									m_rectComboList,
									this, 0, NULL);

				if (!bSuccess)
				{
				}
				else
				{
					m_strInitialComboString = _T("");

					if (!m_bFontIsCreated)
					{
						// use font from list control
						CFont *font = pDC->GetCurrentFont();
						if (font)
						{
							LOGFONT lf;
							font->GetLogFont(&lf);
							m_ListboxFont.CreateFontIndirect(&lf);
							m_bFontIsCreated = TRUE;
						}
					}

					if (m_bFontIsCreated)
						m_pListBox->SetFont(&m_ListboxFont, FALSE);

					if (pXLCD[nSubItem].psa)
					{
						CString s;
						for (int i = 0; i < pXLCD[nSubItem].psa->GetSize(); i++)
						{
							s = pXLCD[nSubItem].psa->GetAt(i);
							if (!s.IsEmpty())
								m_pListBox->AddString(s);
						}
					}

					int index = 0;
					if (str.IsEmpty())
					{
						// str is empty, try to get from first listbox string
						if (m_pListBox->GetCount() > 0)
							m_pListBox->GetText(0, str);

						SetItemText(nItem, nSubItem, str);
					}
					else
					{
						// set listbox selection from subitem text
						index = m_pListBox->FindStringExact(-1, str);
						if (index == LB_ERR)
							index = 0;
					}
					m_pListBox->SetCurSel(index);
					m_pListBox->GetText(index, m_strInitialComboString);
					m_pListBox->SetActive(11);
				}
			}
		}
	}
	pDC->SelectObject(pOldPen);
}

#endif

///////////////////////////////////////////////////////////////////////////////
// DrawCheckbox
void CXListCtrl::DrawCheckbox(int nItem,
							  int nSubItem,
							  CDC *pDC,
							  COLORREF crText,
							  COLORREF crBkgnd,
							  CRect& rect,
							  XLISTCTRLDATA *pXLCD)
{
	ASSERT(pDC);
	ASSERT(pXLCD);

	GetDrawColors(nItem, nSubItem, crText, crBkgnd);

	pDC->FillSolidRect(&rect, crBkgnd);

	CRect chkboxrect;
	chkboxrect = rect;
	chkboxrect.bottom -= 1;
	chkboxrect.left += 9;		// line up checkbox with header checkbox
	chkboxrect.right = chkboxrect.left + chkboxrect.Height();	// width = height

	CString str;
	str = GetItemText(nItem, nSubItem);

	if (str.IsEmpty())
	{
		// center the checkbox

		chkboxrect.left = rect.left + rect.Width()/2 - chkboxrect.Height()/2 - 1;
		chkboxrect.right = chkboxrect.left + chkboxrect.Height();
	}

	// fill rect around checkbox with white
	pDC->FillSolidRect(&chkboxrect, m_crWindow);

	chkboxrect.left += 1;

	// draw border
	pDC->DrawEdge(&chkboxrect, EDGE_SUNKEN, BF_RECT);

	if (pXLCD[nSubItem].nCheckedState == 1)
	{
		CPen *pOldPen = NULL;

		CPen graypen(PS_SOLID, 1, m_crGrayText);
		CPen blackpen(PS_SOLID, 1, RGB(0,0,0));

		if (pXLCD[0].bEnabled)
			pOldPen = pDC->SelectObject(&blackpen);
		else
			pOldPen = pDC->SelectObject(&graypen);

		// draw the checkmark
		int x = chkboxrect.left + 9;
		ASSERT(x < chkboxrect.right);
		int y = chkboxrect.top + 3;
		int i;
		for (i = 0; i < 4; i++)
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x, y+3);
			x--;
			y++;
		}
		for (i = 0; i < 3; i++)
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x, y+3);
			x--;
			y--;
		}

		if (pOldPen)
			pDC->SelectObject(pOldPen);
	}

	if (!str.IsEmpty())
	{
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(crText);
		pDC->SetBkColor(crBkgnd);
		CRect textrect;
		textrect = rect;
		textrect.left = chkboxrect.right + 4;

		pDC->DrawText(str, &textrect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
	}
}

///////////////////////////////////////////////////////////////////////////////
// GetDrawColors
void CXListCtrl::GetDrawColors(int nItem,
							   int nSubItem,
							   COLORREF& colorText,
							   COLORREF& colorBkgnd)
{
	DWORD dwStyle    = GetStyle();
	DWORD dwExStyle  = GetExtendedStyle();

	COLORREF crText  = colorText;
	COLORREF crBkgnd = colorBkgnd;

	if (GetItemState(nItem, LVIS_SELECTED))
	{
		if (dwExStyle & LVS_EX_FULLROWSELECT)
		{
			// selected?  if so, draw highlight background
			crText  = m_crHighLightText;
			crBkgnd = m_crHighLight;

			// has focus?  if not, draw gray background
			if (m_hWnd != ::GetFocus())
			{
				if (dwStyle & LVS_SHOWSELALWAYS)
				{
					crText  = m_crWindowText;
					crBkgnd = m_crBtnFace;
				}
				else
				{
					crText  = colorText;
					crBkgnd = colorBkgnd;
				}
			}
		}
		else	// not full row select
		{
			if (nSubItem == 0)
			{
				// selected?  if so, draw highlight background
				crText  = m_crHighLightText;
				crBkgnd = m_crHighLight;

				// has focus?  if not, draw gray background
				if (m_hWnd != ::GetFocus())
				{
					if (dwStyle & LVS_SHOWSELALWAYS)
					{
						crText  = m_crWindowText;
						crBkgnd = m_crBtnFace;
					}
					else
					{
						crText  = colorText;
						crBkgnd = colorBkgnd;
					}
				}
			}
		}
	}

	colorText = crText;
	colorBkgnd = crBkgnd;
}

///////////////////////////////////////////////////////////////////////////////
// DrawImage
int CXListCtrl::DrawImage(int nItem,
						  int nSubItem,
						  CDC* pDC,
						  COLORREF crText,
						  COLORREF crBkgnd,
						  CRect rect,
  						  XLISTCTRLDATA *pXLCD)
{
	GetDrawColors(nItem, nSubItem, crText, crBkgnd);

	pDC->FillSolidRect(&rect, crBkgnd);

	int nWidth = 0;
	rect.left += m_HeaderCtrl.GetSpacing();

	CImageList* pImageList = GetImageList(LVSIL_SMALL);
	if (pImageList)
	{
		SIZE sizeImage;
		sizeImage.cx = sizeImage.cy = 0;
		IMAGEINFO info;

		int nImage = -1;
		if (pXLCD)
			nImage = pXLCD[nSubItem].nImage;

		if (nImage == -1)
			return 0;

		if (pImageList->GetImageInfo(nImage, &info))
		{
			sizeImage.cx = info.rcImage.right - info.rcImage.left;
			sizeImage.cy = info.rcImage.bottom - info.rcImage.top;
		}

		if (nImage >= 0)
		{
			if (rect.Width() > 0)
			{
				POINT point;

				point.y = rect.CenterPoint().y - (sizeImage.cy >> 1);
				point.x = rect.left;

				SIZE size;
				size.cx = rect.Width() < sizeImage.cx ? rect.Width() : sizeImage.cx;
				size.cy = rect.Height() < sizeImage.cy ? rect.Height() : sizeImage.cy;

				// save image list background color
				COLORREF rgb = pImageList->GetBkColor();

				// set image list background color
				pImageList->SetBkColor(crBkgnd);
				pImageList->DrawIndirect(pDC, nImage, point, size, CPoint(0, 0));
				pImageList->SetBkColor(rgb);

				nWidth = sizeImage.cx + m_HeaderCtrl.GetSpacing();
			}
		}
	}

	return nWidth;
}

//////////////////////////////////////////////////////////////////////////
// 绘制路径
void CXListCtrl::DrawPath( int nItem,
			  int nSubItem,
			  HDC hdc,
			  COLORREF crText,
			  COLORREF crBkgnd,
			  CRect& rect,
			  XLISTCTRLDATA *pXLCD )
{
	GetDrawColors(nItem, nSubItem, crText, crBkgnd);

	Gdiplus::Graphics g( hdc );
	SolidBrush brush( crBkgnd );
	Rect Boundrect( rect.left, rect.top, rect.Width(), rect.Height() );
	g.FillRectangle( &brush, Boundrect );

	int nWidth = 0;
	rect.left += m_HeaderCtrl.GetSpacing();

	// 得到控制点图形
	if ( m_parrPdcs->GetCount() > 0 )
	{
		int nIndex = -1;
		if (pXLCD)
			nIndex = pXLCD[nSubItem].nPathIndex;

		if (nIndex == -1)
			return;

		if ( nIndex >= 0 )
		{
			if ( rect.Width() > 0 )
			{
				// 得到绘制的点图形
				CActionPointDisplayControl *pApdc = (*m_parrPdcs)[ nIndex ];
				CPointShape *pShape = pApdc->GetPointShape();
				GraphicsPath *pPath = &( pShape->m_Path );

				// 得到路径范围
				RectF rectBound;
				pPath->GetBounds( &rectBound );

				// 得到路径的宽度和高度
				Gdiplus::REAL width, height;
				width = rectBound.GetRight() - rectBound.GetLeft();
				height = rectBound.GetBottom() - rectBound.GetTop();

				// 得到路径的中心点位置
				PointF centerPt( rectBound.GetLeft() + width / 2, 
					rectBound.GetTop() + height / 2 );

				// 将图形移动到当前点的位置
				Matrix matrix;
				matrix.Translate( (Gdiplus::REAL)( rect.CenterPoint().x - centerPt.X ), (Gdiplus::REAL)( rect.CenterPoint().y - centerPt.Y ) );

				// 得到绘制区域矩形
				int min = rect.Width();
				if( rect.Width() > rect.Height() )
					min = rect.Height();

				// 设置当前路径为指定大小
				Gdiplus::REAL max = width;
				if( width < height ) max = height;
				Gdiplus::REAL scale = ( min - 4 ) / max;
				matrix.Scale(  scale, scale );

				// 将路径按指定的位移和缩放比率进行变换
				pPath->Transform( &matrix );
				
				// 如果被选中
				if( pXLCD[nSubItem].bPathSelected )
				{
					Pen CoursePen( pApdc->GetSelectColor(), 2 );

					// 绘制图形
					g.DrawPath( &CoursePen, pPath );

					// 是否填充
					if( pShape->m_bFill )
					{
						SolidBrush brush( pApdc->GetSelectColor() );
						g.FillPath( &brush, pPath );
					}
				}
				else
				{
					Pen CoursePen( pApdc->GetColor(), 2 );
					g.DrawPath( &CoursePen, pPath );

					// 是否填充
					if( pShape->m_bFill )
					{
						SolidBrush brush( pApdc->GetColor() );
						g.FillPath( &brush, pPath );
					}
				}
			}
		}
	}
}
///////////////////////////////////////////////////////////////////////////////
// DrawText
void CXListCtrl::DrawText(int nItem,
						  int nSubItem,
						  CDC *pDC,
						  COLORREF crText,
						  COLORREF crBkgnd,
						  CRect& rect,
						  XLISTCTRLDATA *pXLCD)
{
	ASSERT(pDC);
	ASSERT(pXLCD);

	GetDrawColors(nItem, nSubItem, crText, crBkgnd);

	pDC->FillSolidRect(&rect, crBkgnd);

	CString str;
	str = GetItemText(nItem, nSubItem);

	if (!str.IsEmpty())
	{
		// get text justification
		HDITEM hditem;
		hditem.mask = HDI_FORMAT;
		m_HeaderCtrl.GetItem(nSubItem, &hditem);
		int nFmt = hditem.fmt & HDF_JUSTIFYMASK;
		UINT nFormat = DT_VCENTER | DT_SINGLELINE;
		if (nFmt == HDF_CENTER)
			nFormat |= DT_CENTER;
		else if (nFmt == HDF_LEFT)
			nFormat |= DT_LEFT;
		else
			nFormat |= DT_RIGHT;

		CFont *pOldFont = NULL;
		CFont boldfont;

		// check if bold specified for subitem
		if (pXLCD && pXLCD[nSubItem].bBold)
		{
			CFont *font = pDC->GetCurrentFont();
			if (font)
			{

⌨️ 快捷键说明

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