MFC CTreeView SetItemData()的数据的释放

什么情况下会用到SetItemData函数

\qquad 我们在写MFC程序的时候,有时会用到树控件和CTreeView类,我们在生成一棵树之后,希望点击树的一个子节点,然后在右边的对话框或者是List等里面显示这个节点的一个详细信息。这时候,就需要这个树的子节点关联一个变量,可以是下标,可以是地址等等,目的是使得可以方便的找到这个子节点的详细信息,然后显示在别的东西里面。
\qquad 当然,这只是我自己遇到的一个情形,实际的应用里面,应该有很多相似的可能情况吧。
\qquad SetItemData函数的使用也很简单,一个例子:

void CMyTreeView2::UpdateTree()
{
	CTreeCtrl& tree = GetTreeCtrl();
	HTREEITEM hCChild;
	CMFCApplication3Doc* pDoc = (CMFCApplication3Doc*)GetDocument();
	
	int s = 0;
	for (auto p : pDoc->hoInPar.m_ProjectItemArr)
	{
		if (p->HoleTypeID == 1) {
			//在hChild1节点下面插入hCCild这个节点。
			//节点的信息是pWideChar,它是个CString类型的数据。
			hCChild = tree.InsertItem(pWideChar, hChild1);
			subscript* sub1 = new subscript;
			sub1->i = s;
			tree.SetItemData(hCChild, (DWORD_PTR)sub1);
			//删除缓冲区
			delete[]buf;
		}
		if (p->HoleTypeID == 2) {
		}
		if (p->HoleTypeID == 10) {
		}
		s++;
	}
}

上面这个例子是我程序中用到的代码的一个简化版,主要是为了使用SetItemData()这个函数,记住两点:
1.第二个参数要强制转换。
2.第二个参数一定是堆里面的,即是new或者是malloc等动态申请的,这一点尤为重要,我当时就卡在这里卡了很久。不相信,你就用栈里面的,然后在后面用GetItemData()函数取的时候,你就取不到了。

接着就是最后用完了这个东西,要记得释放空间。

\qquad 因为我们是动态申请的空间,所以在后面不用的时候,要记得自己手动的释放空间。
\qquad 释放这些空间对应得消息是TVN_DELETEITEM.建出来的函数是这样的,函数名是OnTvnDeleteitem()

void CMyTreeView2::OnTvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	//reinterpret_cast 强制把 NMHDR类型的指针转换为LPNMTREEVIEW类型的指针。
	// TODO: 在此添加控件通知处理程序代码
	TVITEM& item = pNMTreeView->itemOld;
	if (item.lParam != 0) {
		delete (struct subscript*)item.lParam;
	}
	*pResult = 0;
}

这个函数,会在我们关闭程序或者是关闭树控件这个小的窗口的时候,会自动的调用,包括父子节点一起,一共有多少个,一共就会调用所少次,我先前也看它没有循环,我会担心,它没有完全的释放内存,我就一步一步调试了一遍,确实会把所有的节点都过一遍!大家放心使用。

获取现在鼠标点击的树的子节点

\qquad 到这里,我标题里面的东西已经结束了,下面是我自己记得另外一个函数,就是在点击树的时候,获取当前的鼠标点击的树的节点,这样才可以显示信息。这是实现里面的NM_CLICK消息。

void CMyTreeView2::OnNMClick(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	CTreeCtrl& tree = GetTreeCtrl();
	CPoint CursorPoint;
	if (!GetCursorPos(&CursorPoint))
	{
		return;
	}
	tree.ScreenToClient(&CursorPoint);
	UINT uFlag = 0;
	HTREEITEM select_item = tree.HitTest(CursorPoint, &uFlag);
	if ((NULL != select_item) && (TVHT_ONITEM & uFlag))
	{
		tree.Select(select_item, TVGN_CARET);
	}
	else
	{
		return;
	}
	ShowView(select_item);
	*pResult = 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指针的值是地址

觉得还不错,我会继续努力的。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值