MFC应用技术之CTreeControl的使用

一丶MFC添加树控件.添加父节点跟子节点.

  MFC上面放一个树控件.并未这个树控件绑定变量.然后添加一个按钮.按钮的作用就是添加父节点跟子节点.

PS: 关于MFC如果添加控件.这里不做讲解.此篇只用于应用.所以常用的都会列举出来.

  树控件添加结点注意用的 方法是 InsertItem()

这个方法是重载的有很多种. 这里只讲解自己常用的一种.其余的查询MSDN即可.

添加父节点跟子节点.

void CTreeControlDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM Root = m_RootControl.InsertItem(_T("父节点")); 返回一个句柄
m_RootControl.InsertItem(_T("子节点5"), Root,TVI_SORT); 继续调用这个方法添加的时候.参数二是父节点返回的句柄.则添加结点到父节点下面. 参数三是排序的意思.可以默认不加.
m_RootControl.InsertItem(_T("子节点4"), Root, TVI_SORT);
m_RootControl.InsertItem(_T("子节点3"), Root, TVI_SORT);
m_RootControl.InsertItem(_T("子节点2"), Root, TVI_SORT);
m_RootControl.InsertItem(_T("子节点1"), Root, TVI_SORT); }

应用截图:

  

二丶获取树控件父节点以及子节点

   获取树控件父节点 方法是  GetRootItem() 返回的Item句柄就是父节点. GetChildItem() 则是获取子节点.传入父节点.返回子节点.

   GetItemText(句柄)  返回这个句柄的字符串.  GetParentItem() 获取子节点的父节点.

看如下代码:

  

void CTreeControlDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM Root = m_RootControl.GetRootItem(); //获取顶层结点.
HTREEITEM ChildItem = m_RootControl.GetChildItem(Root);
CString strText = m_RootControl.GetItemText(ChildItem);
AfxMessageBox(strText);
}

应用截图:

  

三丶根据根节点获取兄弟结点

  获取根节点我们知道了.就是GetRootItem(); 那么获取兄弟结点是什么意思?

意思就是兄弟的意思.  假设我们有三个父结点.

  父结点0

  父节点1

  父节点2

我们首先获取父节点0的Item 然后继续获取他的兄弟结点.兄弟结点就是父节点1

方法:  GetNextSiblingItem()  获取指定结点的下一个兄弟

方法: GetPrevSiblingItem();  获取指定结点的上一个兄弟.

具体代码例子:

  

void CTreeControlDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM Root = m_RootControl.GetRootItem(); //获取根节点
HTREEITEM BrothorItem = m_RootControl.GetNextSiblingItem(Root);//获取跟结点的下一个兄弟结点 CString strText = m_RootControl.GetItemText(BrothorItem); //获取兄弟结点的文本穿
AfxMessageBox(strText); }

应用截图:

  

获取上一个兄弟结点

  

void CTreeControlDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM Root = m_RootControl.GetRootItem(); HTREEITEM BrothorItem1 = m_RootControl.GetNextSiblingItem(Root); //获取下一个兄弟结点 这里我们要先获取下一个兄弟.因为根节点的上一个兄弟没有了. HTREEITEM BrothorItem2 = m_RootControl.GetPrevSiblingItem(BrothorItem1); //获取上一个兄弟 这里就是获取第二个节点的上一个兄弟,也就是父节点0 CString strText = m_RootControl.GetItemText(BrothorItem2);
AfxMessageBox(strText); }

应用截图:

  

四丶根据指定结点.递归遍历下面所有子节点.

  上面都是简单的使用. 所以真正使用我们要遍历结点. 比如遍历父节点下面的所有子节点.

递归遍历:

  1.递归遍历指定结点下面所有的子节点

void CTreeControlDlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
//1.获取根节点
HTREEITEM RootItem = m_RootControl.GetRootItem();
IteratorTreeChild(RootItem);
} void CTreeControlDlg::IteratorTreeChild(HTREEITEM item)
{
CString strText = m_RootControl.GetItemText(item); //获取字符串.并且弹出.
AfxMessageBox(strText); //定义两个结点.一个当前结点.一个下一个结点.
HTREEITEM CurItem;
HTREEITEM NextItem; CurItem = m_RootControl.GetChildItem(item); //当前结点是子节点.
while (CurItem != NULL)
{
//继续遍历集结点.
NextItem = CurItem;
IteratorTreeChild(NextItem);
CurItem = m_RootControl.GetNextSiblingItem(NextItem);
}
}

代码只打印了.

  1.传入根节点.

  2.定义两个结点.

  3.当前结点是子节点的Item

  4.下一个结点也是Item

  5.递归遍历.

  6.如果没有.则获取下一个子节点.也就是子节点的兄弟结点.

实现截图:

  

2.循环遍历指定结点下面的一层子节点

上图是递归遍历所有子节点.但是有的时候我们只需要遍历一层即可.

例如下图: 我们只需要遍历到子节点5.

实现代码:

  

void CTreeControlDlg::IteratorTreeChild2(HTREEITEM item) //循环遍历当前父节点的子节点.不深层遍历
{
HTREEITEM CurrItem = m_RootControl.GetChildItem(item); // 获取子节点句柄
CString strText;
while (CurrItem)
{
strText = m_RootControl.GetItemText(CurrItem);
AfxMessageBox(strText);
CurrItem = m_RootControl.GetNextSiblingItem(CurrItem); //获取子节点的兄弟结点即可.
}
} void CTreeControlDlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM RootItem = m_RootControl.GetRootItem(); //根据根节点遍历根节点下面的一层子节点.
IteratorTreeChild2(RootItem);
}

3.递归遍历所有父节点下面的所有子节点

  如果我们要遍历所有父节点.跟他的子节点. 则需要稍微更改下代码即可.也就是第一种代码的改进.

实现代码:

  

void CTreeControlDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码 HTREEITEM RootItem = m_RootControl.GetRootItem();
do
{
IteratorTreeChild1(RootItem); //递归方法是第一种里面的.所以不再重复写了
} while ((RootItem = m_RootControl.GetNextSiblingItem(RootItem)) != NULL); //主要就是这里.循环遍历父节点的兄弟结点. }

4.循环遍历所有父节点下的第一层子节点.

  上面的是遍历父节点下的子节点. 所有的子节点. 子节点的子节点也遍历.但是我们只需要遍历一层

void CTreeControlDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码 HTREEITEM RootItem = m_RootControl.GetRootItem();
HTREEITEM CurItem;
CString strText;
do
{
CurItem = m_RootControl.GetChildItem(RootItem); //双层循环.第一层遍历父节点.第二层遍历子节点的兄弟结点.
while (CurItem)
{
strText = m_RootControl.GetItemText(CurItem);
AfxMessageBox(strText); CurItem = m_RootControl.GetNextSiblingItem(CurItem);
} } while ((RootItem = m_RootControl.GetNextSiblingItem(RootItem)) != NULL); }

常用的遍历差不多就这些了.我们看下响应时间消息

五丶事件消息

  树控件的消息有如下.

通知消息说明

TVN_BEGINDRAG指示拖放操作的开始。

TVN_BEGINLABELEDIT将通知开始就地编辑标签

TVN_BEGINRDRAG使用鼠标右键,终止拖放操作的开始,

TVN_DELETEITEM标志着特定中删除项

TVN_ENDLABELEDIT信号的结束编辑标签

TVN_GETDISPINFO请求树控件需要显示的项的信息。

TVN_ITEMEXPANDED子项父项的列表展开或折叠的信号

TVN_ITEMEXPANDING子项的父项列表会展开或折叠的信号

TVN_KEYDOWN信号键盘事件

TVN_SELCHANGE信号从中选择一项更改为另一个架构

TVN_SELCHANGING指示选定项即将从一项变为另一项

TVN_GETDISPINFO更新的信息通知为维护项

具体可以查询MSDN

MSDN 链接: https://technet.microsoft.com/zh-cn/library/38x8htxs.aspx/

关于我们主要讲解 TVN_SELCHANGE 也就是当选择则会改变.

如果添加事件消息.那么会有如下代码.

void CTreeControlDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码 *pResult = ;
}

这个是给我们默认添加的. 而返回值是微软已经给我们转好的.所以我们需要的信息就在里面.我们可以看下结构内容.

LPNMTREEVIEW 这是一个宏.宽版本还是A版本. 熟悉Windows的都应该知道.
看下对应的结构
typedef struct tagNMTREEVIEWW {
NMHDR hdr;
UINT action;
TVITEMW itemOld; 旧的Item
TVITEMW itemNew; 当前点击的Item
POINT ptDrag; 坐标
} NMTREEVIEWW, *LPNMTREEVIEWW;

里面有一个新的结构体.也就是 TVITEMW

看下这个结构里面内容.

typedef struct tagTVITEMW {
UINT mask;
HTREEITEM hItem; 当前的hitem结构
UINT state; 状态.
UINT stateMask;
LPWSTR pszText; 文本.
int cchTextMax;
int iImage; 图像
int iSelectedImage; 选择图形
int cChildren;
LPARAM lParam; 附加参数
} TVITEMW, *LPTVITEMW;

当然上面是我自己理解的然后加的注释.不过没有错误. 而我们常用的就是 hitem结构.

所以如果我们要获取选择项的item文本就用如下代码.

void CTreeControlDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码 HTREEITEM Root = pNMTreeView->itemNew.hItem;
CStringW str = m_RootControl.GetItemText(Root);
AfxMessageBox(str);
*pResult = ;
}

或者是点击子节点.获取她的父节点.

void CTreeControlDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码 HTREEITEM Child = pNMTreeView->itemNew.hItem;
HTREEITEM Root = m_RootControl.GetParentItem(Child);
CString str = m_RootControl.GetItemText(Root);
AfxMessageBox(str);
*pResult = ;
}
 

MFC应用技术之CTreeControl的使用的更多相关文章

  1. MFC 框架技术简单研讨

    引用:http://www.cnblogs.com/chinazhangjie/archive/2011/09/20/2181986.html 正文: 第一讲 Win32 App  和  MFC Fr ...

  2. MFC多线程技术

    MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没笑消息机制,通常用来执行后台计算和维护任务,如 ...

  3. VC++ MFC橡皮筋技术

    在MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动 //OnLButtionDown        m_ptOrigin = m_ptEnd = point;  //OnMouseMove ...

  4. MFC类别概述

    MFC 类别主要可分为下列数大群组: ■ General Purpose classes - 提供字符串类别.数据处理类别(如数组与串行),异 常情况处理类别.文件类别...等等. ■ Windows ...

  5. MFC 简介

    参考:https://baike.baidu.com/item/MFC/2236974 MFC (微软基础类库) 编辑 锁定 讨论999   MFC(Microsoft Foundation Clas ...

  6. 基于VC++的网络扫描器设计与实现

    本文正文其实是自己的毕业论文,现在搬上来有两个原因. 一是之前大学的文档都放在百度网盘上,大概去年的时候百度网盘改版搞得不太稳定,文件夹移动次数一多里边就会有一些文件丢失了,也没有很在意.但前几天看申 ...

  7. VC++/MFC(VC6)开发技术精品学习资料下载汇总

    工欲善其事,必先利其器,VC开发MFC Windows程序,Visual C++或Visual Studio是必须的,恩,这里都给你总结好了,拿去吧:VC/MFC开发必备Visual C++.Visu ...

  8. 十年MFC经历认识的Microsoft技术 [转]

    十年MFC经历认识的Microsoft技术[原创] 孙辉 自从2005年3月8日下午16时“十年MFC经历认识的Microsoft技术”以帖子的方式发表于CSDN论坛后,引起了许多网友得好评,使得笔者 ...

  9. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:/ ...

随机推荐

  1. Injection

    what java EE提供了注入机制,使您的对象能够获取对资源和其他依赖项的引用,而无需直接实例化它们.通过使用将字段标记为注入点的注释之一来装饰字段或方法,可以在类中声明所需的资源和其他依赖项.然 ...

  2. Mac- appium 环境配置

    一: 下载    appium : https://bitbucket.org/appium/appium.app/downloads/ 下载安装完,打开appium,安全性与隐私设置  检测提示: ...

  3. Unity3D中AssetBundle应用

    工程中的模型等资源转化为Prefab后,打包成AssetBundle,可以大幅降低资源的空间占有度,并且提高资源加载的效率. 一.AssetBundle的打包 先看下打包Prefab的脚本代码,这段脚 ...

  4. Java实现zip压缩文件的解压

    需求描述: 前段时间写了一篇博客<Java实现对文本文件MD5加密并ftp传送到远程主机目录>,实现了一部分的业务需求.然而有些业务可能不止传送一个文件,有时候客户需要传多个文件,原有系统 ...

  5. 自由拖拽DIV实现

    最近在做的项目有个效果是要实现div随意拖拽改变大小,前端框架选择的是vue.js,UI用的是element,拖拽效果可以很简单的实现,但是在拖拽过程中发现会对其他元素实现全选效果,因此最后选择使用元 ...

  6. oracle RAC

         RAC安装步骤       1 配置共享存储      2 Grid Infrastructure软件的安装,GI主要用于cluster ,storage的管理      3 安装数据库软件 ...

  7. CentOS---zabbix使用sendEamil发送报警

    一.sendEmail简介 sendEmail是一个轻量级,命令行的SMTP邮件客户端.如果你需要使用命令行发送邮件,那么sendEmail是非常完美的选择:使用简单并且功能强大.这个被设计用在php ...

  8. HDU1262-寻找素数对

    //#include<bits/stdc++.h> #include<map> #include<cstdio> #include<string> #i ...

  9. 《Node.js高级编程》之Node 核心API基础

    Node 核心API基础 第三章 加载模块 第四章 应用缓冲区 第五章 事件发射器模式简化事件绑定 第六章 使用定时器制定函数执行计划 第三章 加载模块 本章提要 加载模块 创建模块 使用node_m ...

  10. 黑群晖DS3617xs-DSM6.1.7up3/up2 开启ROOT用户,同时SATA改eSATA,挂载NTFS硬盘设置(二)

    这两天闲来没事在某宝上搞了个黑群晖主机就j1900/4G小主机系统是DCM 6.1.7up3 15284版 网上修改的教程很多,走了好多弯路终于搞定我的黑群NAS,现分享给各位道友,有不足的地方请给位 ...