VS2010 MFC TreeControl控件子项的增、删、改、图标、节点选中、控件背景及字体颜色

一、准备一个对话框程序

在这里插入图片描述初始化代码:

BOOL CUserManual::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此处添加初始化树形控件的项
HTREEITEM Hhead  = m_tree.InsertItem(_T("[DamoguUserManual]"), 1, 0, TVI_ROOT);//添加一级结点
HTREEITEM subH1  = m_tree.InsertItem(_T("H86文件"), 1, 0, Hhead);//添加二级结点
HTREEITEM subH2  = m_tree.InsertItem(_T("Hex文件"), 1, 0, Hhead);//添加二级结点
HTREEITEM subH3  = m_tree.InsertItem(_T("H86转换"), 1, 0, Hhead);//添加二级结点

HTREEITEM subH11 = m_tree.InsertItem(_T("校验规则"), 1, 0, subH1);//添加三级结点
HTREEITEM subH12 = m_tree.InsertItem(_T("合成步骤"), 1, 0, subH1);//添加三级结点
HTREEITEM subH13 = m_tree.InsertItem(_T("校验规则"), 1, 0, subH2);//添加三级结点
HTREEITEM subH21 = m_tree.InsertItem(_T("合成步骤"), 1, 0, subH2);//添加三级结点
HTREEITEM subH22 = m_tree.InsertItem(_T("转换需知"), 1, 0, subH3);//添加三级结点    

m_tree.SetBkColor(RGB(255, 255, 255));  //设置树形控件的背景色
m_tree.SetTextColor(RGB(127, 0, 0));    //设置文本颜色
m_tree.SetLineColor(RGB(0, 150, 220));	//设置线的颜色
m_tree.Select(subH1, TVGN_CARET);       //子项subH1为选定项
// TODO: 结束TreeControl代码
return TRUE;  // return TRUE unless you set the focus to a control
}

效果如下:
在这里插入图片描述
现在为界面添加:
在这里插入图片描述
头文件引入变量:
CTreeCtrl m_tree;

增加按钮代码

void CUserManual::OnBnClickedBtnTreeadd()
{
// TODO: 在此添加控件通知处理程序代码
CString strInput;
GetDlgItemTextW(IDC_TreeEdit1, strInput);
HTREEITEM hItem = m_tree.GetSelectedItem();

if (!hItem)
   hItem = TVI_ROOT;

TVINSERTSTRUCTW ts = { 0 };
ts.hParent = hItem;
ts.itemex.pszText = (LPWSTR)(LPCTSTR)strInput;  // 转换
                   // Long Point Width String
                   // Long Point Const Type String
ts.item.mask = TVIF_TEXT;
ts.hInsertAfter = TVI_LAST;

HTREEITEM hNewItem = m_tree.InsertItem(&ts);
m_tree.SelectItem(hNewItem);
m_tree.EnsureVisible(hNewItem);
}

二 、删除代码按钮

void CUserManual::OnBnClickedBtnTreedel()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM hItem = m_tree.GetSelectedItem();
if (!hItem)
   return;
//HTREEITEM hParentItem = m_tree.GetParentItem(hItem);
m_tree.DeleteItem(hItem); // 在vs2015环境下,这一行代码就可以,在删除一个节点之后,会自动选中下一个节点
                         // 但是,如果在比较老的编译器下,可能还需要上一行和下一行的代码,来保证删除后
                         // 选择下一个节点的功能
//m_tree.SelectItem(hParentItem);
}

三、修改按钮代码

void CUserManual::OnBnClickedBtnTreeedit()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM hItem = m_tree.GetSelectedItem();
if (!hItem)
   return;

CString strInput;
GetDlgItemTextW(IDC_TreeEdit1, strInput);
m_tree.SetItemText(hItem, strInput);
}

类向导加入
在这里插入图片描述代码如下:

void CUserManual::OnSelchangedTreemanual(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

 // TODO: 在此添加控件通知处理程序代码
 HTREEITEM hItem = m_tree.GetSelectedItem();
 if (hItem)
 {
     CString strInput = m_tree.GetItemText(hItem);
     SetDlgItemTextW(IDC_TreeEdit1, strInput);
 }
*pResult = 0;
}

Tree属性设置如下

在这里插入图片描述
效果如下:
在这里插入图片描述
四、展开所有节点

//.h
void CUserManual::ExpandAllNode(HTREEITEM hItem, CTreeCtrl& treeShow);
//.cpp
//OnInitDialog
ExpandAllNode(m_tree.GetRootItem(), m_tree); // 展开所有节点
//Function API
void CUserManual::ExpandAllNode(HTREEITEM hItem, CTreeCtrl& treeShow)
{
   HTREEITEM hChild = treeShow.GetChildItem(hItem);
while(hChild)
{
   treeShow.Expand(hItem, TVE_EXPAND);
   ExpandAllNode(hChild, treeShow);
   hChild = treeShow.GetNextSiblingItem(hChild);
}
}

效果如下:
在这里插入图片描述
打开窗口后全部展开

五、载入图标,设置指定名称的节点的图标
在上述基础上,增加

//.h
void SetTreeNodeIcon(HTREEITEM hStartItem, CTreeCtrl& treeCtrl, CString csNodeName);
//.init
HICON hIcon[1];      // 图标句柄
hIcon[1] = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
SetTreeNodeIcon(m_tree.GetRootItem(), m_tree, _T("H86文件"));
void CUserManual::SetTreeNodeIcon(HTREEITEM hStartItem, CTreeCtrl& treeCtrl, CString csNodeName)
{
   HTREEITEM hChild = treeCtrl.GetChildItem(hStartItem);
   while(hChild)
   {
    if(csNodeName == treeCtrl.GetItemText(hChild))
    {
	 treeCtrl.SetItemImage(hChild, 1, 1);
	 return ;
     } else  {
	  SetTreeNodeIcon(hChild, treeCtrl, csNodeName);
	  hChild = treeCtrl.GetNextSiblingItem(hChild);
     }
   }
}

效果如下:
在这里插入图片描述

六、Tree控件列表前加图标
四个步骤

//加载三个图标,并将它们的句柄保存到数组   
HICON Icon[4];
Icon[0]=AfxGetApp()->LoadIcon(IDI_ICON1);
Icon[1]=AfxGetApp()->LoadIcon(IDI_ICON2);
Icon[2]=AfxGetApp()->LoadIcon(IDI_ICON3);
Icon[3]=AfxGetApp()->LoadIcon(IDI_ICON4);

// 创建图像序列CImageList对象   
CImageList *m_imageList;
m_imageList.Create(20, 20, ILC_COLOR32, 3, 3); 

// 将三个图标添加到图像序列   
for(int i=0;i<4;i++)
{
  m_imageList->Add(Icon[i]); //读入图标
}

// 为树形控件设置图像序列  
CTreeCtrl m_tree;
m_tree.SetImageList(&m_imageList, TVSIL_NORMAL);

函数原型

 HTREEITEM InsertItem(LPCTSTR lpszItem,
                      int nImage,
                      int nSelectedImage,
                      HTREEITEM hParent = TVI_ROOT,
                      HTREEITEM hInsertAfter = TVI_LAST);
//lpszItem为新节点的标签文本字符串的指针
//nImage为新节点的图标在树形控件图像序列中的索引
//nSelectedImage为新节点被选中时的图标在图像序列中的索引
//hParent为插入节点的父节点的句柄
//hInsertAfter为新节点的前一个节点的句柄,
//即新节点将被插入到hInsertAfter节点之后

函数原型

BOOL Create(
            int cx,
            int cy,
            UINT nFlags,
            int nInitial,
            int nGrow 
//图片的实际像素宽与高
//图片的实际像素宽与高
//创建图像列表的类型,包括4/8/16/24/32/位色
//创建ImageList初始包括的图像个数
//当初始分配的图像个数不够的时候,新增一个图片时,指定图象列表
//能增加的新图象个数,图像列表空间不够而继续添加image时,将按
//照nGrow继续分配空间,设计时根据具体情况设置合适的值,避免内
//存频繁的改变图像列表而過度頻繁而使系統记忆体碎片化
);

例如
nInitial = 2,nGrow=3
当你添加了两个图像元素以后,还想添加第三个的时候,初始创建分配的nInitial已经使用完了,此时,系统会根据nGrow,为自动增大Imagelist3个元素容量,此时我们的Imagelist就可以容纳5个图像元素了,如果5个使用完毕后,会继续按照nGrow进行再分配,类似于一个可变数组,但参数到底设置多少,还是要根据实际的情况设置合理的值,一要避免浪费空间,又要避免频繁的对Image容器进行resize操作

函数原型
如果树节点需要显示图标时,则必须先创建一个CImageList类的对象,并为其添加多个图像组成一个图像序列,然后调用SetImageList函数为树形控件设置图像序列,在用InsertItem插入节点时传入所需图像在图像序列中的索引即可。


CImageList* SetImageList(CImageList * pImageList,
                                int   nImageListType);
//pImageList为指向图像序列类CImageList的对象的指针,
//若为NULL则删除树形控件的所有图像。
//nImageListType指定图像序列的类型,可以是TVSIL_NORMAL(普通图像序列)
//或TVSIL_STATE(状态图像序列,用图像表示节点的状态)。

相关控件解释,这篇文章写得比较详细,可以参考 >| 传送门

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要设置MFC ListControl控件的行背景,您需要使用自定义绘制来绘制背景。以下是示例代码: 1.在您的ListControl类的头文件中添加以下成员变量: ``` CBrush m_brush; // 用于绘制行背景的画刷 ``` 2.在您的ListControl类的构造函数中初始化画刷: ``` m_brush.CreateSolidBrush(RGB(255, 255, 255)); // 创建白色画刷 ``` 3.覆盖ListControl类的OnCustomDraw方法: ``` BOOL CMyListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); *pResult = CDRF_DODEFAULT; switch (lpLVCustomDraw->nmcd.dwDrawStage) { case CDDS_PREPAINT: *pResult = CDRF_NOTIFYITEMDRAW; // 通知每个子项绘制 break; case CDDS_ITEMPREPAINT: // 获取当前子项的颜色和绘制矩形 COLORREF clr = RGB(255, 255, 255); // 默认颜色为白色 CRect rc; GetItemRect(lpLVCustomDraw->nmcd.dwItemSpec, &rc, LVIR_BOUNDS); // 根据需要设置颜色 if (lpLVCustomDraw->nmcd.dwItemSpec % 2 == 0) clr = RGB(238, 238, 238); // 偶数行为浅灰色 else clr = RGB(255, 255, 255); // 奇数行为白色 // 绘制背景 CDC* pDC = CDC::FromHandle(lpLVCustomDraw->nmcd.hdc); CBrush* pOldBrush = pDC->SelectObject(&m_brush); pDC->FillSolidRect(rc, clr); pDC->SelectObject(pOldBrush); *pResult = CDRF_NEWFONT; // 允许更字体 break; case CDDS_ITEMPOSTPAINT: *pResult = CDRF_DODEFAULT; break; } return TRUE; } ``` 在上面的代码中,我们使用了CDDS_ITEMPREPAINT阶段来绘制行背景。在这个阶段,我们可以获取当前子项的颜色和绘制矩形,然后使用画刷填充矩形。在CDDS_ITEMPREPAINT阶段结束后,您可以在CDDS_ITEMPOSTPAINT阶段绘制其他内容。 请注意,上面的代码仅提供了一种设置行背景的方法。如果您需要实现更复杂的背景,您需要根据自己的需求进行修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CDamogu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值