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

最近用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
}
编译运行后效果如下所示
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值