让ListBox控件每一行显示不同的颜色

原创 2013年12月03日 14:47:16

最近用MFC做个小项目,想要让ListBox中的每一行都根据自定义的颜色来显示不同的颜色。刚开始把MFC想的太简单了,拖了一个ListBox控件然后绑定了一个变量m_ListBox。

在主对话框的OnInitDialog()函数中我调用了下面的代码

m_ListBox.AddString(_T("这是一个小测试!"));
m_ListBox.SetItemData(0,RGB(0,0,255));
运行后发现显示的仍是默认的黑色。

后来查阅相关资料,才发现微软将这些控件的字体和颜色等属性都是设置为默认的,普通的属性设置函数根本没用。要想在ListBox或者ListCtrl等控件中绘制你想要的图形或者设置你想要的属性,那么必须采用自绘的方式。

界面方面的编程有时就是一层窗户纸,捅破了就好。下面是实现的具体过程:

1.拖一个ListBox控件设置一下属性。其中Owner draw属性要设置成Variable,Has strings要勾选


2.自定义一个派生自CListBox的类CColorListBox。重载下面两个虚函数

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
然后定义一个接口用来让我们调用,根据传入的字符串和RGB值让ListBox的每一行根据我们自定义的颜色来显示

public:
	int AddString(LPCTSTR lpszItem, COLORREF itemColor = RGB(255,0,0));

下面是上面3个函数的具体定义


////////////////////////////////////////////////////////

/********************************************************************/
/*																	*/
/* Function name : AddString										*/		
/* Description   : Add string to the listbox and save color info.	*/
/*																	*/
/********************************************************************/
int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF itemColor)
{
	// Add the string to the list box
	int nIndex = CListBox::AddString(lpszItem);
   
	// save color data
	if (nIndex >= 0)
		SetItemData(nIndex, itemColor);

	return nIndex;
}


/********************************************************************/
/*																	*/
/* Function name : DrawItem											*/		
/* Description   : Called by the framework when a visual aspect of	*/
/*				   an owner-draw list box changes.					*/
/*																	*/
/********************************************************************/
void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    // Losing focus ?
    if (lpDrawItemStruct->itemID == -1) 
	{
		DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);
		return;
    }

	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

	COLORREF clrOld;
	CString sText;
	
	// get color info from item data
	COLORREF clrNew = (COLORREF)(lpDrawItemStruct->itemData);

	// item selected ?
	if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&
		 (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
	{
		CBrush brush(::GetSysColor(COLOR_HIGHLIGHT));
		pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);
	}

	// item deselected ?
	if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&	
		(lpDrawItemStruct->itemAction & ODA_SELECT))
	{
		CBrush brush(::GetSysColor(COLOR_WINDOW));
		pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);
	}	 	

	// item has focus ?
	if ((lpDrawItemStruct->itemAction & ODA_FOCUS) && 
		(lpDrawItemStruct->itemState & ODS_FOCUS))
	{
		pDC->DrawFocusRect(&lpDrawItemStruct->rcItem); 
	}

	// lost focus ?
	if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&	
		!(lpDrawItemStruct->itemState & ODS_FOCUS))
	{
		pDC->DrawFocusRect(&lpDrawItemStruct->rcItem); 
	}

	// set the background mode to TRANSPARENT
	int nBkMode = pDC->SetBkMode(TRANSPARENT);

	if (lpDrawItemStruct->itemState & ODS_SELECTED)
		clrOld = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
	else 
	if (lpDrawItemStruct->itemState & ODS_DISABLED)
		clrOld = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
	else
		clrOld = pDC->SetTextColor(clrNew);

	// get item text
	GetText(lpDrawItemStruct->itemID, sText);
	CRect rect = lpDrawItemStruct->rcItem;

	// text format
	UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
	if (GetStyle() & LBS_USETABSTOPS)
		nFormat |= DT_EXPANDTABS;
	
	// draw the text
	pDC->DrawText(sText, -1, &rect, nFormat);

	// restore old values
	pDC->SetTextColor(clrOld); 
	pDC->SetBkMode(nBkMode);
}


void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
	lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENUCHECK);	
}

3.现在我们可以测试一下。拖一个ListBox控件,然后定义一个CColorListBox 类型的变量m_ListBox。你可以直接在下面所对应的位置手动添加如下代码,也可以通过MFC ClassWizard自动添加。

在主对话框头文件中头文件中添加

// Dialog Data
	//{{AFX_DATA(CLogSystemTestDlg)
         ........
	CColorListBox	m_ListBox;
	//}}AFX_DATA

在主对话框的代码文件中的DoDataExchange()函数中添加代码

DDX_Control(pDX, IDC_LIST1, m_ListBox);
目的是将变量m_ListBox和IDC_LIST1标识的列表控件绑定,具体代码如下

void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLogSystemTestDlg)
	DDX_Control(pDX, IDC_LIST1, m_ListBox);
	//}}AFX_DATA_MAP
}

在主对话框的代码文件中的OnInitDIalog()函数中添加测试代码

BOOL CLogSystemTestDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	...........
	// TODO: Add extra initialization here
	m_ListBox.AddString("空山新雨后",RGB(255,0,0));
	m_ListBox.AddString("天气晚来秋",RGB(0,255,0));
	m_ListBox.AddString("明月松间照",RGB(0,0,255));
	m_ListBox.AddString("清泉石上流",RGB(255,0,255));
	return TRUE;  // return TRUE  unless you set the focus to a control
}


编译运行后效果如下所示


vc修改列表框LISTBOX的背景颜色及字体颜色及其使用方法

vc修改列表框LISTBOX的背景颜色及字体颜色及其使用方法 收藏  一、修改背景颜色及字体颜色①   先创建一个基于对话框的工程,命名为test,然后在对话框上加入一个ListBox控件。     ...
  • s3c44b0x
  • s3c44b0x
  • 2010年03月23日 15:50
  • 5502

MFC自绘ListBox可根据条件定义不同行字体颜色

MFC自绘ListBox可根据条件定义不同行字体颜色头文件#if!defined(AFX_MULITLINELISTBOX_H__D705CB99_9FD0_424E_BD71_027547449AE...
  • u010143011
  • u010143011
  • 2015年04月29日 13:41
  • 1507

MFC之ListBox控件样式扩展

MFC中有许多控件,将控件拖到窗口中右键鼠标,点击属性,到样式标签页中会有很多样式可以选择 但是往往这些样式会满足不了我们的需求,这时候,我们需要自己来完成我们想要的样式控件 我们就来拿ListB...
  • iq19900204
  • iq19900204
  • 2011年09月27日 00:44
  • 4665

C#中动态修改ListBox的Item的颜色的方法

最近搞了C#需要在ListBox中显示不同类型的数据,为了让用户容易区分
  • cumtwys
  • cumtwys
  • 2014年07月24日 16:59
  • 5232

listbox隔行显示不同颜色

winform ListBox隔行显示不同文本颜色
  • hws1058648831a
  • hws1058648831a
  • 2014年01月17日 13:44
  • 2826

改变ListBox中Items的颜色,并且为ListBox中的项目添加图片。

改变ListBox中Items的颜色,并且为ListBox中的项目添加图片。这个很简单,只需要下面几个步骤:1.      DrawMode属性设置为自己画// ListBox1is ListBox ...
  • diandian82
  • diandian82
  • 2006年08月01日 12:42
  • 3635

设置ListBox选中项的背景颜色

[html] view plain copy   Style x:Key="UserItemContainerStyle" TargetType="ListBoxItem">       ...
  • tieshuxianrezhang
  • tieshuxianrezhang
  • 2017年02月06日 15:44
  • 798

在C#中控制ListBox某一行的字体颜色

private void Form1_Load(object sender, EventArgs e) { listBox1.Items.Add("红色"); listBox1.Ite...
  • jyh_jack
  • jyh_jack
  • 2014年02月07日 13:27
  • 7680

改变Listbox中的字体颜色

                                          改变Listbox中的字体颜色        当用ListBox来作输出显示的时候,有时需要针对不同的输出显示不同的...
  • tjvictor
  • tjvictor
  • 2007年01月20日 13:21
  • 11798

关于VS2010中使用CColorListBox 实现文本改变颜色

过程: 1)使用别人已经写好的类,CColorListBox 完成。其实过程很简单,只是在vs2010 中需要注意一些细节:    首先,在新建的项目中加入这两个类;    然后,  在vs对话...
  • zhoxier
  • zhoxier
  • 2012年04月20日 14:06
  • 2074
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:让ListBox控件每一行显示不同的颜色
举报原因:
原因补充:

(最多只允许输入30个字)