“树状视图控件”是一个显示项目层次列表的窗口,例如文档中的标题、索引中的条目或磁盘上的文件和目录。每个项目都由一个标签和一个可选的位图图像组成,每个项目都可以有一个与其相关联的子项目列表。通过单击项目,用户可以展开和折叠子项目的关联列表。CTreeCtrl类提供了Windows通用树状视图控件的功能
CTreeCtrl类的父类为CWnd。要使用CTreeCtrl类,需包含的头文件为afxcmn.h,即:#include
可用Create函数创建树状视图控件并与一个CTreeCtrl对象关联。CTreeCtrl类的Create函数原型如下:
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
返回值:
如果初始化成功则返回非零值;否则返回0。
参数:
dwStyle | 指定tree view控件的风格。可以对这个控件使用tree view控件风格的任意组合。 |
rect | 指定tree view控件的尺寸和位置。此参数可以是一个CRect对象或一个RECT结构。 |
pParentWnd | 指定tree view控件的父窗口,通常是一个CDialog。它不能是NULL。 |
nID | 指定tree view控件的ID。 |
说明:
构造一个CTreeCtrl要分两步。首先调用构造函数,然后调用Create来创建这个tree view控件并将它与该CTeeCtrl对象连接。
下面的风格可以应用到一个tree view控件:
· | TVS_HASLINES | tree view控件的子项与它们的父项之间用线连接。 |
· | TVS_LINESATROOT | tree view控件用线连接子项和根项。 |
· | TVS_HASBUTTONS | tree view在每一个父项的左边添加一个按钮。 |
· | TVS_EDITLABELS | tree view控件允许用户编辑tree view项的标签。 |
· | TVS_SHOWSELALWAYS | 当tree view失去焦点时,使被选择的项仍然保持被选择。 |
· | TVS_DISABLEDRAGDROP | 该tree view控件被禁止发送。 |
· | TVN_BEGINDRAG | 通知消息。 |
· | TVS_NOTOOLTIPS | tree view控件使用工具提示。 |
· | TVS_SINGLEEXPAND | 当使用这个风格时,改变在tree view中的选择将导致正被选择的项展开,而没有被选择的项收缩。如果用鼠标单击被选择的项,并且该项是关闭的,则该项就会展开。如果该被选择的项被单击时是打开的,则它就会收缩。 |
CTreeCtrl类还有以下成员函数:
属性
GetCount | 获取与一个treeview控件相关联的tree项的数目 |
GetIndent | 获取一个tree view项对它的父项的偏移(以像素表示) |
SetIndent | 设置一个tree view项对它的父项的偏移(以像素表示) |
GetImageList | 获取与一个tree view控件相关联的图像列表的句柄 |
SetImageList | 设置与一个tree view控件相关联的图像列表的句柄 |
GetNextItem | 获取与指定的关系匹配的下一个tree view项 |
ItemHasChildren | 如果指定项有子项则返回非零值 |
GetChildItem | 获取一个指定tree view项的子项 |
GetNextSiblingItem | 获取指定tree view项的下一个兄弟项 |
GetPrevSiblingItem | 获取指定tree view项的前一个兄弟项 |
GetParentItem | 获取指定tree view项的父项 |
GetFirstVisibleItem | 获取指定tree view项的第一个可视项 |
GetNextVisibleItem | 获取指定tree view项的下一个可视项 |
GetPrevVisibleItem | 获取指定tree view项的前一个可视项 |
GetSelectedItem | 获取当前被选择的tree view项 |
GetDropHilightItem | 获取一次拖放操作的目标 |
GetRootItem | 获取指定tree view项的根 |
GetItem | 获取一个指定tree view项的属性 |
SetItem | 设置一个指定tree view项的属性 |
GetItemState | 返回一个项的状态 |
SetItemState | 设置一个项的状态 |
GetItemImage | 获取与一个项相关联的图像 |
SetItemImage | 设置与一个项相关联的图像 |
GetItemText | 返回一个项的文本 |
SetItemText | 设置一个项的文本 |
GetItemData | 返回与一个项关联的32位的应用程序指定值 |
SetItemData | 设置与一个项关联的32位的应用程序指定值 |
GetItemRect | 获取一个tree view项的边界矩形 |
GetEditControl | 获取用来编辑指定tree view项的编辑控件的句柄 |
GetVisibleCount | 获取与一个tree view项关联的可视tree项的编号 |
GetToolTips | 获取一个tree view控件使用的子ToolTip控件的的句柄 |
SetToolTips | 设置一个tree view控件的子ToolTip控件的的句柄 |
GetBkColor | 获取控件的当前背景颜色 |
SetBkColor | 设置控件的背景颜色 |
GetItemHeight | 获取tree view项的当前高度 |
SetItemHeight | 设置tree view项的当前高度 |
GetTextColor | 获取控件的当前文本颜色 |
SetTextColor | 设置控件的文本颜色 |
SetInsertMark | 设置一个tree view控件的插入标记 |
GetCheck | 获取一个tree控件项的核选状态 |
SetCheck | 设置一个tree控件项的核选状态 |
GetInsertMarkColor | 获取tree view用来绘制插入标记的颜色 |
SetInsertMarkColor | 设置tree view用来绘制插入标记的颜色 |
操作
InsertItem | 在一个tree view控件中插入一个新项。 |
DeleteItem | 从一个tree view控件中删除一个项 |
DeleteAllItems | 从一个tree view控件中删除所有的项 |
Expand | 展开或收缩指定tree view项的子项 |
Select | 选择,在视中滚动,或重画一个指定的tree view项 |
SelectItem | 选择一个指定的tree view项 |
SelectDropTarget | 重画作为一次拖放操作的目标的tree项 |
SelectSetFirstVisible | 选择一个指定的tree view项作为第一个可视项 |
EditLabel | 现场编辑一个指定的tree view项 |
HitTest | 返回与CtreeCtrl关联的光标的当前位置 |
CreateDragImage | 为指定的tree view项创建一个拖动位图 |
SortChildren | 排序一个给定父项的子项 |
EnsureVisible | 确保一个tree view项在它的tree view控件中是可视的 |
SortChildrenCB | 使用一个由应用程序定义的排序函数来排列一个给定父项的子项 |
下面以实例演示树状视图控件的创建,及其常用成员函数的使用。
1.创建一个MFC对话框项目CTreeTest,然后在对话框的头文件中声明一个CTreeCtrl变量m_TreeCtrl;,如下:
// CCTreeTestDlg 对话框
class CCTreeTestDlg : public CDialogEx
{
// 构造
public:
CCTreeTestDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_CTREETEST_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CTreeCtrl m_TreeCtrl;
};
2. 在OnInitDialog()中加入生成、显示树状视图的代码,如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
添加的代码为:
点击菜单“调试”“开始执行(不调试)”,结果如下:
对话框中显示出一个白色矩形框,这就是通过代码创建的树状视图控件。当然我们也可以通过将工具箱中的树状视图控件拖到对话框中来创建,如下图:
点击菜单“调试”“开始执行(不调试)”,结果如下:
多出了一个矩形白框,这个白框就是新添加的树状视图控件。
3. 插入内容 (从工具箱添加的CTreeCtrl控件需关联一个CTreeCtrl变量,再通代码实现),在OnInitDialog()中继续添加代码如下:
插入该代码段的OnInitDialog()函数如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"),0,0);
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"), 1, 1, Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), 1, 1, Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), 1, 1, Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
执行程序(不调试),结果如下:
Expand函数用于展开或收缩Tree View项的子,其原型如下:
BOOL Expand( HTREEETEM hItem, UINT nColor );
返回值:如果成功则返回非零值;否则返回0。
参数:
hItem | 要被扩展的tree项的句柄。 | ||||||||||||
nCode | 用来指示要被进行的动作的标志。这个标志可以是下列值之一:
|
注释掉含Expand函数的代码行,执行结果如下:
说明在没有调用该函数时,子项是收缩的,如果不明白这点,可能会误以为添加子项失败。
继续添加如下代码:
插入该代码段的OnInitDialog()函数如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"),0,0);
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"), 1, 1, Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), 1, 1, Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), 1, 1, Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
m_TreeCtrl.InsertItem(_T("张三"), 2, 2, Grade1);
m_TreeCtrl.InsertItem(_T("李军"), 2, 2, Grade1);
m_TreeCtrl.InsertItem(_T("王勇"), 2, 2, Grade1);
m_TreeCtrl.InsertItem(_T("王强"), 2, 2, Grade1);
m_TreeCtrl.InsertItem(_T("刘梅"), 2, 2, Grade2);
m_TreeCtrl.InsertItem(_T("李辉"), 2, 2, Grade2);
m_TreeCtrl.InsertItem(_T("刘伟"), 2, 2, Grade2);
m_TreeCtrl.InsertItem(_T("萧蔷"), 2, 2, Grade2);
m_TreeCtrl.InsertItem(_T("陈蔷"), 2, 2, Grade3);
m_TreeCtrl.InsertItem(_T("刘胜"), 2, 2, Grade3);
m_TreeCtrl.InsertItem(_T("李希"), 2, 2, Grade3);
m_TreeCtrl.InsertItem(_T("王敏"), 2, 2, Grade3);
m_TreeCtrl.Expand(Grade1, TVE_EXPAND);
m_TreeCtrl.Expand(Grade2, TVE_EXPAND);
m_TreeCtrl.Expand(Grade3, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
执行程序(不调试),结果如下:
上面的代码段中仿佛用到了函数InsertItem,修改上面代码中InsertItem函数的参数如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"),0,0);
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"), 1, 1, Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), 1, 1, Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), 1, 1, Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
m_TreeCtrl.InsertItem(_T("张三"), 0, 0, Grade1);
m_TreeCtrl.InsertItem(_T("李军"), 0, 0, Grade1);
m_TreeCtrl.InsertItem(_T("王勇"), 0, 0, Grade1);
m_TreeCtrl.InsertItem(_T("王强"), 2, 0, Grade1);
m_TreeCtrl.InsertItem(_T("刘梅"), 2, 1, Grade2);
m_TreeCtrl.InsertItem(_T("李辉"), 2, 2, Grade2);
m_TreeCtrl.InsertItem(_T("刘伟"), 2, 3, Grade2);
m_TreeCtrl.InsertItem(_T("萧蔷"), 2, 4, Grade2);
m_TreeCtrl.InsertItem(_T("陈蔷"), 3,3, Grade3);
m_TreeCtrl.InsertItem(_T("刘胜"), 3, 3, Grade3);
m_TreeCtrl.InsertItem(_T("李希"), 3, 3, Grade3);
m_TreeCtrl.InsertItem(_T("王敏"), 3, 3, Grade3);
m_TreeCtrl.Expand(Grade1, TVE_EXPAND);
m_TreeCtrl.Expand(Grade2, TVE_EXPAND);
m_TreeCtrl.Expand(Grade3, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
执行程序(不调试),结果如下:
奇怪,尽管参数变了,执行结果确是一样的。下面来看一下InsertItem函数,器原型如下:
HTREEITEM InsertItem( LPTVINSERTSTRUCT lpInsertStruct );
HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEM hInsertAfter );
HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );
HTREEITEM InsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);
Return Value
Handle of the new item if successful; otherwise NULL.
参数:
lpInsertStruct | 一个指向用来指定要插入的tree view项的属性的TVINSERTSTRUCT的指针。 |
nMask | 用来指定要设置的属性的整数。 |
lpszItem | 一个包含项的文本的字符串的地址。 |
nImage | 项的图像在tree view控件的图像列表中的索引。 |
nSelectedImage | 项的被选择图像在tree view控件的图像列表中的索引。 |
nState | 为项的状态指定的值。 |
nStateMask | 指定要设置的状态。 |
lParam | 与此项关联的一个32位的应用程序指定的值。 |
hParent | 要被插入的项的父项的句柄。 |
hInsertAfter | 新项要被插入其后的项的句柄。 |
实际上我们用的是最后一个原型函数,变更到的是与图像有关的参数,由于没有设定相关的图像列表,所以这个变更并不影响显示结果。此时使用第三个原型函数更好,修改OnInitDialog()函数中的代码如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"));
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"),Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
m_TreeCtrl.InsertItem(_T("张三"),Grade1);
m_TreeCtrl.InsertItem(_T("李军"), Grade1);
m_TreeCtrl.InsertItem(_T("王勇"),Grade1);
m_TreeCtrl.InsertItem(_T("王强"),Grade1);
m_TreeCtrl.InsertItem(_T("刘梅"), Grade2);
m_TreeCtrl.InsertItem(_T("李辉"),Grade2);
m_TreeCtrl.InsertItem(_T("刘伟"), Grade2);
m_TreeCtrl.InsertItem(_T("萧蔷"), Grade2);
m_TreeCtrl.InsertItem(_T("陈蔷"),Grade3);
m_TreeCtrl.InsertItem(_T("刘胜"), Grade3);
m_TreeCtrl.InsertItem(_T("李希"), Grade3);
m_TreeCtrl.InsertItem(_T("王敏"),Grade3);
m_TreeCtrl.Expand(Grade1, TVE_EXPAND);
m_TreeCtrl.Expand(Grade2, TVE_EXPAND);
m_TreeCtrl.Expand(Grade3, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
执行程序(不调试),结果如下:
结果一样的。当然OnInitDialog()函数中的代码修改如下,也是可以的。
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"));
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"),Grades, Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), Grades, Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), Grades, Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
m_TreeCtrl.InsertItem(_T("张三"), Grade1,Grade1);
m_TreeCtrl.InsertItem(_T("李军"), Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("王勇"),Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("王强"),Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("刘梅"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("李辉"),Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("刘伟"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("萧蔷"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("陈蔷"),Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("刘胜"), Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("李希"), Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("王敏"),Grade3, Grade3);
m_TreeCtrl.Expand(Grade1, TVE_EXPAND);
m_TreeCtrl.Expand(Grade2, TVE_EXPAND);
m_TreeCtrl.Expand(Grade3, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
如果当一个项目含有子项时,当未展开时,前面需出现个+号,如何处理呢,只需修改函数参数如下即可(或上了TVS_HASBUTTONS):
m_TreeCtrl.Create(TVS_HASLINES|TVS_HASBUTTONS, CRect(0, 0, 0, 0), this, 0x1005);
执行程序(不调试),结果如下:
4. 事件响应 为动态添加的CTreeCtrl控件添加事件处理函数相对比较麻烦,这里以从工具箱添加到对话框中的CTreeCtrl控件为例,演示添加事件处理函数。
首选将控件关联一个变量(已经添加好,所以为灰色),如下:
修改控件属性如下:
修改OnInitDialog()函数中的代码如下:
BOOL CCTreeTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_TreeCtrl.Create(TVS_HASLINES|TVS_HASBUTTONS, CRect(0, 0, 0, 0), this, 0x1005);
m_TreeCtrl.MoveWindow(20,20,200,300);
m_TreeCtrl.ShowWindow(SW_SHOW);
HTREEITEM Grades = m_TreeCtrl.InsertItem(_T("Grade"));
HTREEITEM Grade1= m_TreeCtrl.InsertItem(_T("Grade 1"),Grades, Grades);
HTREEITEM Grade2 = m_TreeCtrl.InsertItem(_T("Grade 2"), Grades, Grades);
HTREEITEM Grade3 = m_TreeCtrl.InsertItem(_T("Grade 3"), Grades, Grades);
m_TreeCtrl.Expand(Grades, TVE_EXPAND);
m_TreeCtrl.InsertItem(_T("张三"), Grade1,Grade1);
m_TreeCtrl.InsertItem(_T("李军"), Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("王勇"),Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("王强"),Grade1, Grade1);
m_TreeCtrl.InsertItem(_T("刘梅"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("李辉"),Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("刘伟"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("萧蔷"), Grade2, Grade2);
m_TreeCtrl.InsertItem(_T("陈蔷"),Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("刘胜"), Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("李希"), Grade3, Grade3);
m_TreeCtrl.InsertItem(_T("王敏"),Grade3, Grade3);
m_TreeCtrl.Expand(Grade1, TVE_EXPAND);
m_TreeCtrl.Expand(Grade2, TVE_EXPAND);
m_TreeCtrl.Expand(Grade3, TVE_EXPAND);
HTREEITEM Grades2 = m_CTreeCtrl2.InsertItem(_T("Grade"));
HTREEITEM Grade2_1 = m_CTreeCtrl2.InsertItem(_T("Grade 1"),Grades2);
HTREEITEM Grade2_2 = m_CTreeCtrl2.InsertItem(_T("Grade 2"),Grades2);
HTREEITEM Grade2_3 = m_CTreeCtrl2.InsertItem(_T("Grade 3"),Grades2);
m_CTreeCtrl2.Expand(Grades2, TVE_EXPAND);
m_CTreeCtrl2.InsertItem(_T("张三"), Grade2_1);
m_CTreeCtrl2.InsertItem(_T("李军"), Grade2_1);
m_CTreeCtrl2.InsertItem(_T("王勇"), Grade2_1);
m_CTreeCtrl2.InsertItem(_T("王强"), Grade2_1);
m_CTreeCtrl2.InsertItem(_T("刘梅"), Grade2_2);
m_CTreeCtrl2.InsertItem(_T("李辉"), Grade2_2);
m_CTreeCtrl2.InsertItem(_T("刘伟"), Grade2_2);
m_CTreeCtrl2.InsertItem(_T("萧蔷"), Grade2_2);
m_CTreeCtrl2.InsertItem(_T("陈蔷"), Grade2_3);
m_CTreeCtrl2.InsertItem(_T("刘胜"), Grade2_3);
m_CTreeCtrl2.InsertItem(_T("李希"), Grade2_3);
m_CTreeCtrl2.InsertItem(_T("王敏"), Grade2_3);
m_CTreeCtrl2.Expand(Grade2_1, TVE_EXPAND);
m_CTreeCtrl2.Expand(Grade2_2, TVE_EXPAND);
m_CTreeCtrl2.Expand(Grade2_3, TVE_EXPAND);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
执行程序(不调试),结果如下:
添加事件处理函数 ,选中类视图中的·CCTreeTestDlg,
按鼠标右键选中属性,进入属性列表,如下:
点击事件图标,选中IDC_TREE2,可看到事件列表如下:
这里选中TVN_SELCHANGED,并添加事件处理函数,如下:
添加的事件处理函数如下:
我们在该函数中添加代码,完成后如下:
void CCTreeTestDlg::OnTvnSelchangedTree2(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
HTREEITEM mitem = m_CTreeCtrl2.GetSelectedItem();
CString str = m_CTreeCtrl2.GetItemText(mitem);
CString str1;
str1.Format(_T("你选中的是%s"), str);
MessageBox(str1);
*pResult = 0;
}
执行程序(不调试),结果如下:
点击右边CTreeCtrl中的“王敏:,结果如下:
CTreeCtrl控件有很多成员函数,这里就不一一演示了,需进一步了解其使用可查阅MSDNLibrary。