【MFC】设置CTreeCtrl单个节点的文字颜色
问题
功能调整需要依据不同状态设置树控件中单个节点的文字颜色。
分析
1、CTreeCtrl本身有设置文字颜色的接口SetTextColor,但是这个接口是设置树控件整体的文字颜色。
2、在自定义接口可以对树控件单个节点进行更新文字颜色和背景颜色,接收自定义绘制消息NM_CUSTOMDRAW。
解决
1、头文件中定义自定义绘制接口
// .h 文件
//...
// 定义自定义绘制接口
afx_msg void OnNMCustomdrawTree(NMHDR *pNMHDR, LRESULT *pResult);
//...
// 定义树控件变量
CTreeCtrl m_treeList;
2、cpp文件中接收消息并实现接口
// .cpp 文件
// 接收消息
BEGIN_MESSAGE_MAP(ModelTreeDlg, CDialogEx)
//...
ON_NOTIFY(NM_CUSTOMDRAW, IDC_TREE_MODEL, &OnNMCustomdrawTreeModel)
END_MESSAGE_MAP()
// 实现接口
void OnNMCustomdrawTreeModel(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
if (NULL == pLVCD)
return;
*pResult = CDRF_DODEFAULT;
*pResult |= CDRF_NOTIFYITEMDRAW;
*pResult |= CDRF_NOTIFYSUBITEMDRAW;
*pResult |= CDRF_NOTIFYPOSTPAINT;
const DWORD dwDrawStage = pLVCD->nmcd.dwDrawStage;
if (dwDrawStage != CDDS_ITEMPOSTPAINT || tree.m_bScolling)
return;
// 获取树控件范围
CRect treeRect;
m_treeList.GetClientRect(treeRect);
//界面重绘,树节点后添加图标
HTREEITEM hItem = (HTREEITEM)pLVCD->nmcd.dwItemSpec;
CRect textRect;
if(tree.GetItemRect(hItem, &textRect, TRUE) == false)
return;
//获取节点的文本文字
CString txt = tree.GetItemText(hItem);
CDC* pdc = CDC::FromHandle(pLVCD->nmcd.hdc);
// 设置背景颜色
pdc->FillSolidRect(&textRect, GetSysColor(COLOR_WINDOW));
// 设置文字颜色,默认黑色,依据实体状态更新
COLORREF color = RGB(255, 255, 255);
color = GetSysColor(COLOR_WINDOWTEXT);
pdc->SetTextColor(color);
// 一定要调用 不然不会更新颜色显示
pdc->TextOut(textRect.left + 2, textRect.top + 2, txt);
}
3、搞定!效果如下: