您的位置:首页 > 其它

MFC中CTreeCtrl类的一些基本用法

2012-10-24 19:29 369 查看

MFC中CTreeCtrl类的一些基本用法

最近做课程设计是用到了树形控件,原来对树形控件的用法基本都忘了,这次又重新整合了一下,以加深记忆。

树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点。CTreeCtrl类封装了树形控件的各种操作。在树形控件中每一个结点都有一个HTREEITEM句柄,这个句柄按我的理解其实就是一些十六进制的数,就是用来标识的ID。但是我们通常添加到树形结构的结点都是一些图标或者字符串,这时可以调用:

CString CTreeCtrl::GetItemText(HTREEITEM hItem);

来获得句柄为hItem的显示字符。同理:

BOOL CTreeCtrl::SetItemText( HTREEITEM hItem, LPCTSTR lpszItem );

来将句柄为hItem的显示字符设置为lpszItem 。

一般我们创建了一个树形控件之后就要对这个控件添加结点,CTreeCtrl类提供了一个函数:

HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );

来帮助我们,这个函数的返回值是新添加结点的HTREEITEM句柄,函数的参数lpszItem是要添加结点的显示字符,hParent代表父结点的句柄,默认为根节点,当前添加的结点会排在hInsertAfter表示的结点的后面,默认是添加在最后。利用这个方法我们可以递归添加无穷的结点。下面的代码会建立一个如下形式的树形结构:

+--- Parent1

+--- Child1_1

+--- Child1_2

+--- Child1_3

+--- Parent2

+--- Parent3

/*假设m_tree为一个CTreeCtrl对象,而且该窗口已经创建*/

HTREEITEM hItem,hSubItem;

hItem = m_tree.InsertItem("Parent1",TVI_ROOT);在根结点上添加Parent1

hSubItem = m_tree.InsertItem("Child1_1",hItem);//在Parent1上添加一个子结点

hSubItem = m_tree.InsertItem("Child1_2",hItem,hSubItem);//在Parent1上添加一个子结点,排在Child1_1后面

hSubItem = m_tree.InsertItem("Child1_3",hItem,hSubItem);

hItem = m_tree.InsertItem("Parent2",TVI_ROOT,hItem);

hItem = m_tree.InsertItem("Parent3",TVI_ROOT,hItem);

此外如果想遍历树可以使用下面的函数:

HTREEITEM GetRootItem( );得到根结点。

HTREEITEM GetChildItem( HTREEITEM hItem );得到子结点。

HTREEITEM GetPrevSiblingItem/GetNextSiblingItem( HTREEITEM hItem );得到指明结点的上/下一个兄弟结点。

HTREEITEM GetParentItem( HTREEITEM hItem );得到父结点。

我的程序中利用了这些函数添加了一个三层结构的树,其中考虑了一些结点重复(重复的结点不添加)的问题,发现CTreeCtrl中并没有合适的函数可以使用,于是就自己写了一个,代码如下:

BOOL IsTreeSubItemExist(CTreeCtrl* pTree,HTREEITEM hParent,CString szCurrent)

{

HTREEITEM hChild=pTree->GetChildItem(hParent); //得到子结点

while(hChild!=NULL) //遍历子结点

{

if(pTree->GetItemText(hChild)==szCurrent)

break;

hChild=pTree->GetNextSiblingItem(hChild);

}

if(hChild==NULL)

return FALSE;

else

return TRUE;

}

这个函数用来确定pTree中句柄为hParent的结点是否存在显示字符为szCurrent的结点,若存在返回真,不存在返回假。

在这个函数的基础上,我又写了一个添加的完整的代码,如下:

void CMyView::UpdateTreeViewCtrl()

{

CTreeCtrl* pMyTree=(CTreeCtrl*)this->GetDlgItem(IDC_TREE_MAINALLMSG);

HTREEITEM hItem;

HTREEITEM hSubItem;

CElectricDevice* pNextDevice=m_pFirst->m_nextDevice;

while(pNextDevice!=NULL)

{

if(!IsTreeSubItemExist(pMyTree,TVI_ROOT,pNextDevice->m_brand))

{

hItem=pMyTree->InsertItem(pNextDevice->m_brand,TVI_ROOT);

hSubItem=pMyTree->InsertItem(pNextDevice->m_style,hItem);

pMyTree->InsertItem(pNextDevice->m_type,hSubItem);

}

pNextDevice=pNextDevice->m_nextDevice;

}

pNextDevice=m_pFirst->m_nextDevice;

while(pNextDevice!=NULL)

{

hItem=pMyTree->GetChildItem(TVI_ROOT);

while(hItem!=NULL)

{

if(pMyTree->GetItemText(hItem)==pNextDevice->m_brand)

break;

hItem=pMyTree->GetNextSiblingItem(hItem);

}

if(hItem!=NULL)

{

if(!IsTreeSubItemExist(pMyTree,hItem,pNextDevice->m_style))

{

hSubItem=pMyTree->InsertItem(pNextDevice->m_style,hItem);

pMyTree->InsertItem(pNextDevice->m_type,hSubItem);

}

}

pNextDevice=pNextDevice->m_nextDevice;

}

pNextDevice=m_pFirst->m_nextDevice;

while(pNextDevice!=NULL)

{

hItem=pMyTree->GetChildItem(TVI_ROOT);

while(hItem!=NULL)

{

HTREEITEM hSubSubItem=pMyTree->GetChildItem(hItem);

while(hSubSubItem!=NULL)

{

if(pMyTree->GetItemText(hItem)==pNextDevice->m_brand && pMyTree->GetItemText(hSubSubItem)==pNextDevice->m_style)

{

if(!IsTreeSubItemExist(pMyTree,hSubSubItem,pNextDevice->m_type))

{

pMyTree->InsertItem(pNextDevice->m_type,hSubSubItem);

}

}

hSubSubItem=pMyTree->GetNextSiblingItem(hSubSubItem);

}

hItem=pMyTree->GetNextSiblingItem(hItem);

}

pNextDevice=pNextDevice->m_nextDevice;

}

}

这个函数基本上实现我的目标,但是我觉得在算法上不是很有效率,由于代码很简单我也不介绍了,等有了改进的方法我会再来更新的。

CTreeCtrl还有很多其他的丰富的方法目前此次也没有用到,就只介绍我用到的这些吧!以后用到之后再来补上!

原文:http://hi.baidu.com/hcq11/item/b137ac492b4ea108e93504c8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: