C++ mfc 之 CTreeCtrl

本文讨论在MFC中使用CTreeCtrl时遇到的问题:如何在用户点击节点时高效更新其所有子节点及孙子节点。在文件动态增删的场景下,文中列举了三种策略:不更新原有子节点、全面刷新和寻找优化解决方案,并分析了各自的优缺点和实际效果。针对Windows XP下加号显示不实时的问题,作者正在寻求更优的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在界面开发中,我们首先保证,在正常情况下,自己的程序不出错。另外,还要考虑, 用户各种的使用习惯,是否会导致程序崩溃,极限条件测试等....

在软件开发中,有时为了满足某一方面的要求,不得不牺牲另一方面的要求为代价。

上面的两句话,引出下文的中心。


mfc 的CTreeCtrl类,相信大多人都使用过。如下图,当我们单击【计算机】的时候,

 

我们要更新以【计算机】为父节点的所有子节点,以及孙子节点。

那么当我们单机【本地磁盘(C:)】时,以此为节点的子节点已经更新完成了,但孙子节点需要更新。

so 问题来了。。。

对于此子节点我们怎么做呢?

方法一:

void CXXXView::InitTree(HTREEITEM hitem)
{
 		 HTREEITEM htmp= m_tree.GetParentItem(hitem);
 		 if(htmp)
 		 {
  			 htmp= m_tree.GetParentItem(htmp);
  			 if(htmp==hParam)
  				  return ;
 		 }

		HTREEITEM hCurrent = m_tree.GetChildItem(hitem);
		if (hCurrent == NULL)
		{
			CString strFull = GetFullPath(hitem);
			strFull = strFull.Mid(strFull.Find(_T("\\"))+1);
			strFull += _T("*");

			CFileFind ff;
			bool b=ff.FindFile(strFull);
		
			while(b)
			{
				b=ff.FindNextFile();
				if(ff.IsHidden())
					continue;
				if(ff.IsDots())
					continue;
				if(ff.IsDirectory())
				{
					InitTree(m_tree.InsertItem(ff.GetFileName(),0,0,hitem));
				}
			}
		}else
		{
			//这样写有问题啊?
			while (hCurrent != NULL)
			{
				if(hCurrent)InitTree(hCurrent);
				hCurrent = m_tree.GetNextItem(hCurrent, TVGN_NEXT);
				
			}
		}
}

方法一:原先有的,就不做更新了,新的继续添加。但在我们的项目中,文件的添加和删除都是动态的。不符合情况。

方法二:

void CXXXView::InitTree(HTREEITEM hitem)
{
		HTREEITEM htmp= m_tree.GetParentItem(hitem);
		if(htmp)
		{
			htmp= m_tree.GetParentItem(htmp);
			if(htmp==hParam)
				return ;
		}

		HTREEITEM hCurrent = m_tree.GetChildItem(hitem);
		while (hCurrent != NULL)
		{
			htmp = hCurrent;
			hCurrent = m_tree.GetNextItem(hCurrent, TVGN_NEXT);
			m_tree.DeleteItem(htmp);
		}

		CString strFull = GetFullPath(hitem);
		strFull = strFull.Mid(strFull.Find(_T("\\"))+1);
		strFull += _T("*");

		CFileFind ff;
		bool b=ff.FindFile(strFull);

		while(b)
		{
			b=ff.FindNextFile();
			if(ff.IsHidden())
				continue;
			if(ff.IsDots())
				continue;
			if(ff.IsDirectory())
			{
				InitTree(m_tree.InsertItem(ff.GetFileName(),0,0,hitem));
			}
		}

}

方法二:此方法代价有点大啊!

              也考虑过在线程中做,测试过,但用户体验不好,WINDOW XP 系统下,文件夹前面的加号显示的不实时。

当然,综合前两种方法,就是第三种了

方法3:查看了MSDN的API,好像没有什么简单的方法,如果能通过文件名查到对应的Item就好了,GetItem(),测试过了,好像不行啊。

自己也有一些方法,但觉得不高大上啊!

思考中。。。

 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值