《实用VC编程之玩转控件》第15课:Tree树形控件 - Go语言中文社区

《实用VC编程之玩转控件》第15课:Tree树形控件


本文转载自:VC驿站

https://www.cctry.com/thread-297465-1-1.html

1、控件简介:
Tree树形控件也是我们编程过程中比较常用的一个控件,而且在其他软件中也经常能看到,比如Windows系统中的资源管理器:
《实用VC编程之玩转控件》第15课:Tree树形控件 

所以,接下来我就教大家如何来使用这个控件!

2、控件的使用:
a、拖拽Tree树形控件到对话框模版上;
b、一些常用的属性:
Check Boxes:结点前是否带有复选框;
Edit Labels:结点名字是否可编辑;
Has Buttons:父节点是否有+号可供展开;
Has Lines:父子结点之间是否有连接线;
Lines At Root:是否从根节点开始就带有虚线;
等等吧,大家可以根据自己的需要设置相关的属性。

c、为Tree树形控件绑定一个 CTreeCtrl 控件类型变量m_Tree;

3、控件的操作:
在树形控件中每一个结点都有一个句柄(HTREEITEM),同时插入结点时必须提供父结点句柄,(其中根Root结点只有一个,既不可以添加也不可以删除)利用
HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );
可以插入一个结点,pszItem为显示的字符,hParent代表父结点的句柄,当前添加的结点会排在hInsertAfter表示的结点的后面,返回值为当前创建的结点的句柄。

a、添加结点(有多种重载方式,先介绍第一种):

    HTREEITEM hRoot = m_Tree.InsertItem(_T("父1"));
    HTREEITEM hSub1 = m_Tree.InsertItem(_T("子1"), hRoot);
    HTREEITEM hSub2 = m_Tree.InsertItem(_T("子2"), hRoot);

    HTREEITEM hSub3 = m_Tree.InsertItem(_T("子子1"), hSub2);

《实用VC编程之玩转控件》第15课:Tree树形控件 

就这样,可以一层一层的向树形控件中插入节点。

b、获得节点的文本:m_Tree.GetItemText(hSub3);
c、设置节点的文本:m_Tree.SetItemText(hSub3, _T("abc"));

d、获得当前选中的节点:HTREEITEM hSelItem = m_Tree.GetSelectedItem();
e、设置当前选中的节点:m_Tree.SelectItem(hTreeItem);
f、默认上面的情况都是针对单选,那么Tree树形控件支不支持多选呢?答案是:默认不支持
不过可以通过给节点前面加上 CheckBox 复选框来解决!下个知识点举例讲解!
备注:那么不通过CheckBox 能不能实现多选呢?答案也是可以的,不过要写很多自定义代码,大家感兴趣的话可以看看这几篇文章,课堂上咱们就不讲解了:
http://www.codeguru.com/cpp/cont ... d/article.php/c629/
http://www.codeguru.com/cpp/cont ... d/article.php/c723/
http://www.codeguru.com/cpp/cont ... /article.php/c9219/

g、遍历子节点:
需要用到的相关函数:

HTREEITEM GetRootItem( ); //得到根结点。
HTREEITEM GetChildItem(HTREEITEM hItem); //得到子结点。
HTREEITEM GetPrevSiblingItem/GetNextSiblingItem(HTREEITEM hItem); //得到指明结点的上/下一个兄弟结点。
HTREEITEM GetParentItem(HTREEITEM hItem); //得到父结点。

《实用VC编程之玩转控件》第15课:Tree树形控件 

从根节点开始遍历所有节点,判断 CheckBox 是否勾选:
void CMFCTestDlg::EnumTreeItem(HTREEITEM hItem)
{
    if (!hItem) return;

    //先检测自己是否被勾选
    if (m_Tree.GetCheck(hItem))
    {
        CString strText = m_Tree.GetItemText(hItem);
        MessageBox(strText + _T("##勾选了!"));
    }

    //再遍历所有的子节点
    if (m_Tree.ItemHasChildren(hItem))
    {
        HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
        while (hChildItem)
        {
            EnumTreeItem(hChildItem);
            HTREEITEM hNextItem = m_Tree.GetNextItem(hChildItem, TVGN_NEXT);
            hChildItem = hNextItem;
        }
    }
}

void CMFCTestDlg::OnBnClickedBtnTree()
{
    HTREEITEM hRootItem = m_Tree.GetRootItem(); //从根节点开始遍历
    EnumTreeItem(hRootItem);
}

h、删除节点、删除所有节点:

m_Tree.DeleteItem(hSub2); //删除节点
m_Tree.DeleteAllItems();    //删除所有节点

i:展开/收起所有节点:

void CMFCTestDlg::ExpandTree(HTREEITEM hItem, UINT nCode)
{
    if (!hItem) return;

    m_Tree.Expand(hItem, nCode);
    if (m_Tree.ItemHasChildren(hItem))
    {
        HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
        while (hChildItem)
        {
            ExpandTree(hChildItem, nCode);
            HTREEITEM hNextItem = m_Tree.GetNextItem(hChildItem, TVGN_NEXT);
            hChildItem = hNextItem;
        }
    }
}

void CMFCTestDlg::OnBnClickedBtnTree()
{
    HTREEITEM hRootItem = m_Tree.GetRootItem(); //从根节点开始遍历
    static UINT nCode = TVE_EXPAND;
    ExpandTree(hRootItem, nCode);
    nCode = (nCode == TVE_EXPAND) ? TVE_COLLAPSE : TVE_EXPAND;
}

j:编辑节点文本:
①、控件的 Edit Labels 属性设置为 True;
②、响应控件的 TVN_BEGINLABELEDIT 事件:

void CMFCTestDlg::OnTvnBeginlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
    
    CEdit *pEdit = m_Tree.GetEditControl();
    if (pEdit) pEdit->LimitText(5);//设置编辑框文本长度为5个字符串

    *pResult = 0; //继续
    //*pResult = 1; //取消,不继续编辑,也不触发 TVN_ENDLABELEDIT
}

③、响应控件的 TVN_ENDLABELEDIT 事件:

void CMFCTestDlg::OnTvnEndlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
    if (pTVDispInfo && pTVDispInfo->item.pszText && _tcslen(pTVDispInfo->item.pszText))
    {
        m_Tree.SetItemText(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
    }
    *pResult = 0;
}


k、插入带图标的节点:
这里面给大家准备几个ico图标,供程序使用:
《实用VC编程之玩转控件》第15课:Tree树形控件 ico.zip

①、将几个ico图标文件添加到工程资源中,ID分别为:IDI_ICON1、IDI_ICON2、IDI_ICON3
②、在对话框类类的头文件中加入对象声明:CImageList m_TreeImage;
③、在对话框的初始化函数中创建图像列表:BOOL bRet = m_TreeImage.Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 1);
④、添加图标资源到图像列表:

int iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

⑤、关联Tree树形控件和图像列表:m_Tree.SetImageList(&m_TreeImage, TVSIL_NORMAL);
⑥、将InsertItem插入节点的代码改为:

HTREEITEM hRoot = m_Tree.InsertItem(_T("根"), 0, 1);
HTREEITEM hSub1 = m_Tree.InsertItem(_T("子1"), 0, 1, hRoot);
HTREEITEM hSub2 = m_Tree.InsertItem(_T("子2"), 0, 1, hRoot);

HTREEITEM hSub3 = m_Tree.InsertItem(_T("子子3"), 0, 1, hSub2);

《实用VC编程之玩转控件》第15课:Tree树形控件 

这样就可以啦~!

其中 InsertItem 的第二个参数0和第三个参数1是ico图标在ImageList中的索引,第二个参数是节点默认的图标,第三个参数是节点被选中后的图标。

4、开源控件类:
codeproject 上面关于 Tree树形控件 的开源控件类可谓是很多啊,这里面给大家分享一下,需要哪种自己直接拿过去用就行了:

https://www.codeproject.com/Arti ... port-for-HTML-XML-S
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... -Supports-Transpare
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Articles/6597/CDeviceTree
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... -select-folders-and
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Articles/2243/COptionTree
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... operty-Tree-Control
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... gImage-in-CTreeCtrl
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... heckboxes-Supported
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... esque-Owner-Drawn-C
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... l-that-has-Open-Clo
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... Millers-COptionTree
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Articles/768/CNetworkTreeCtrl
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... FX-and-CHourglassFX
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Articles/2913/A-Tree-List-Control
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... wn-TreeList-Control
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... th-ToolTip-Based-On
《实用VC编程之玩转控件》第15课:Tree树形控件 

https://www.codeproject.com/Arti ... ontrol-with-Columns
《实用VC编程之玩转控件》第15课:Tree树形控件 

5、小作业:
①、给Tree树形控件添加右键弹出菜单,菜单中有个复制的菜单项,点击可以复制结点的文本;
②、点选控件的 CheckBox 后,实际上当前选中的结点不是我点击的结点,能否做到勾选CheckBox 之后,就选中该结点;
③、实现三态CheckBox,可以直接找开源类来实现:https://www.codeproject.com/Articles/847799/CQuadStateTree

具体操作细节见视频教程的演示和讲解!

第15课免费试看,下载地址:

https://www.cctry.com/thread-297465-1-1.html

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/net_syc/article/details/84993906
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 16:29:06
  • 阅读 ( 770 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢