最近在项目中遇到一个问题,就是要设置Tree Control控件中节点的背景色和节点文字的颜色。在网上找了很多资料,发现最常用的方式是响应控件的NM_CUSTOMDRAW消息。具体的实现步骤如下:
1、在VS里面新建一个MFC对话框的工程名为“TestTreeControl”,删除默认添加的静态文本框。然后在工具箱中拖入一个Tree Control控件和一个Button控件,调整控件的位置和大小。
2、修改树控件的ID为IDC_TREEVIEW,按钮的ID为IDC_ADDNODE,Caption属性为Add Node。
3、给树控件添加一个关联的变量m_treeCtrl 类型为CTreeCtrl。(vs中添加方法:选中控件点击右键,在弹出的菜单中选择“添加变量”,弹出添加变量对话框,默认是添加控件变量,类别为Control,给变量取一个名字然后点击“确定”按钮)。
4、 双击“Add Node”按钮跳转到按钮的点击事件函数,在这里添加加入节点到树控件的代码。如下所示:
void CTestTreeControlDlg::OnBnClickedAddnode()
{
// TODO: 在此添加控件通知处理程序代码
CString strText=_T("");
HTREEITEM hRoot;
hRoot = m_treeCtrl.InsertItem(_T("根节点"));//插入树根
TV_INSERTSTRUCT tcItem;//插入数据项数据结构
tcItem.hParent=hRoot;//增加根项
tcItem.hInsertAfter=TVI_LAST;//在最后项之后
tcItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE;//设屏蔽
tcItem.item.pszText="NODE1";
tcItem.item.lParam=1000;//序号
tcItem.item.iImage=0;//正常图标
m_treeCtrl.InsertItem(&tcItem);
tcItem.item.pszText="NODE2";
tcItem.item.lParam=2000;//序号
m_treeCtrl.InsertItem(&tcItem);
tcItem.item.pszText="NODE3";
tcItem.item.lParam=3000;//序号
m_treeCtrl.InsertItem(&tcItem);
m_treeCtrl.Expand(hRoot, TVE_EXPAND);
}
5、在OnInitDialog()函数中添加如下代码
// TODO: 在此添加额外的初始化代码
static CImageList clst;
clst.Create(16,16,ILC_COLOR8,2,2);
clst.Add(AfxGetApp()->LoadIconA(IDI_PICTURE));
m_treeCtrl.SetImageList(&clst,TVSIL_NORMAL);
DWORD dwStyles=GetWindowLong(m_treeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格
dwStyles |= TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
SetWindowLong(m_treeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格
6、为树控件添加事件处理程序。选择树控件点击右键,弹出的菜单中选择“添加时间处理程序”,在弹出的对话框中,在消息类型下拉列表中选中NM_CUSTOMDRAW消息,然后点击“添加编辑”按钮,进入时间处理函数。
7、在事件处理函数中添加如下代码
void CTestTreeControlDlg::OnNMCustomdrawTreeview(NMHDR *pNMHDR, LRESULT *pResult)
{
*pResult = CDRF_DODEFAULT;
NMTVCUSTOMDRAW* plvoid = reinterpret_cast(pNMHDR);
if(CDDS_PREPAINT == plvoid->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if(CDDS_ITEMPREPAINT == plvoid->nmcd.dwDrawStage)
{
COLORREF crText, crBkgnd;
if(plvoid->iLevel == 1) //判断节点所在的层次,根节点在第0层
{
if(plvoid->nmcd.lItemlParam == 1000) //在添加节点时设置了节点的lParam属性,在这里就利用来判定具体是哪个节点
{
crText = RGB(0,0,0);
crBkgnd = RGB(125,125,125);
plvoid->clrText = crText; //设置文字颜色
plvoid->clrTextBk = crBkgnd; //设置背景颜色
}
else if(plvoid->nmcd.lItemlParam == 2000)
{
crText = RGB(0,0,0);
crBkgnd = RGB(125,125,0);
plvoid->clrText = crText;
plvoid->clrTextBk = crBkgnd;
}
else
{
crText = RGB(0,0,0);
crBkgnd = RGB(255,255,255);
}
}
else
{
crText = RGB(0,0,0);
crBkgnd = RGB(255,255,255);
}
*pResult = CDRF_DODEFAULT;
}
}