vc++ Tree Control使用总结

   目前软件的数据曲线绘制模块,需要用到TreeCtrl控件,在学习使用这个控件的过程中,再次感受到了自己的编程基本功、利用MSDN自学能力的不足,以及来自MFC做界面的不便,现在基础还差,等再巩固一段时间的windows编程以及MFC知识后,一定要学Duilib,系统的掌握一套自己的做界面的方法,不要总在界面上浪费这么多时间。
需要利用TreeCtrl实现的功能:
1、创建 多个根节点,每个根节点有多个子节点;
2、每个节点前有checkBox选择框,选中(取消)根节点后,此节点的所有子节点同步变化;
3、选中一个节点checkBox后,自动为此节点的文本分配一种颜色,跟之前文本的颜色有明显的区分,双击节点可以自定义修改颜色,此颜色作为要绘制的曲线的颜色;
4、可以 全选和清空;
5、按部分字符串快速查找节点,如通过搜索“高度”字符串,可以快速定位到第一个文本中包含高度的节点,如“仪器高度”,高亮节点文本,再次点击搜索按钮,可以定位到下一个文本中含有高度的节点,如此循环,类似vs编译器的查找功能;
6、全部遍历;
7、可以动态修改节点文本。
 
为了实现这些功能,一些重要的步骤:
一、设置控件属性:Check Boxes:TRUE , Has Buttons:True , Has Lines:True , Lines At Root:True ,Edit Labels:True ;
二、初始化
   1、添加控件变量 CTreeCtrl m_treeCtrl;
   2、添加根节点HTREEITEM hRoot = m_treeCtrl.InsertItem(_T("根节点"));
      添加子节点HTREEITEM hChidl = m_treeCtrl.InsertItem(_T("子节点"),hRoot);
      注:由于根节点和子节点的个数都是固定的,可以预先定义根节点和子节点的HTREEITEM数组,这样在修改颜色,节点文本,以及遍历节点时都更加方便,当然如果需要         动态的添加删除节点,就不能用这种方法。
   
三、添加TreeCtrl事件处理程序
   1、选中根节点的checkBox,所属的子节点也同步全部选中。需要添加NM_CLICK的消息处理函数:
void CTreeCtrlClassDlg::OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	CPoint p;

	GetCursorPos(&p);

	m_treeCtrl.ScreenToClient(&p);

	UINT nFlag;

	HTREEITEM h=m_treeCtrl.HitTest(p,&nFlag);

	if((h !=  NULL)&&(TVHT_ONITEMSTATEICON & nFlag))  

	{   
		if (m_treeCtrl.ItemHasChildren(h))
		{
			HTREEITEM hChild= m_treeCtrl.GetChildItem(h);
			while(NULL!=hChild)
			{
				m_treeCtrl.SetCheck(hChild,!m_treeCtrl.GetCheck(h));
				hChild= m_treeCtrl.GetNextSiblingItem(hChild);
			}		
	}

	
}
   2、程序运行时,可以修改节点标题,首先属性Edit Labels设置True,然后添加TVN_ENDLABELEDIT消息处理函数:
<pre class="cpp" name="code">void CTreeCtrlClassDlg::OnTvnEndlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	CString strText;
	m_treeCtrl.GetEditControl()->GetWindowText(strText);
	m_treeCtrl.SetItemText(pTVDispInfo->item.hItem,strText);
	*pResult = 0;
} 
   3、右键节点标题改变节点文本颜色,添加NM_RCLIK消息相应函数:
<pre class="cpp" name="code">void CTreeCtrlClassDlg::OnNMRclickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	CPoint p;

	GetCursorPos(&p);

	m_treeCtrl.ScreenToClient(&p);

	UINT nFlag;

	HTREEITEM h=m_treeCtrl.HitTest(p,&nFlag);

	if((h !=  NULL)&&(TVHT_ONITEMLABEL & nFlag)&&m_treeCtrl.GetCheck(h))  
	{
		CColorDialog dlg; 
		COLORREF curColor;
		//打开颜色对话框,获取选定的颜色 
		if(dlg.DoModal()==IDOK) 
		{
			curColor=dlg.GetColor();
			m_treeCtrl.SetItemColor(h,curColor);
		}
	}
}
    注:TreeCtrl类本身并没有SetItemColor改变单个节点文本颜色的函数,我是在网上找了个TreeCtrl的派生类,添加了这个功能函数,想要这个类的可以联系我。
四、遍历节点和全选/清空节点
由于程序中预先定义了根节点和子节点的HTREEITEM数组,所以遍历和全选时非常方便,一个for循环,检查每个节点的getCheck就搞定了。

 


版权声明:本文为woaisia原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。