CTreeCtrl 如何用SetItemData使Item保持额外数据?
主 题: CTreeCtrl 如何用SetItemData使Item保持额外数据?
作 者: huyoo (空格键)
还是先看看下面我写的代码吧~~
定义了两个数据类型
一个枚举类型,ITEM_TYPE
typedef enum tagITEM_TYPE
{
//数据类型
TYPE_TYPE_FOLDER=1,TYPE_FILE
}ITEM_TYPE;
一个数据结构,用来定义额外数据
struct Extra_DATA
{
//Extra 数据
ITEM_TYPE type;
LPCTSTR url;
};
想问一下,我下面的操作,为什么不能使使Item保持额外数据?
难道Item自己没有空间保持额外数据吗?非得要给那些数据分配一些内存?
// ExtraTreeView.cpp : implementation of the CExtraTreeView class
//
#include "stdafx.h"
#include "Extratest.h"
#include "ExtratestDoc.h"
#include "ExtraTreeView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView
typedef enum tagITEM_TYPE
{
//数据类型
TYPE_TYPE_FOLDER=1,TYPE_FILE
}ITEM_TYPE;
struct Extra_DATA
{
//Extra 数据
ITEM_TYPE type;
LPCTSTR link;
};
extern CExtratestApp theApp;
IMPLEMENT_DYNCREATE(CExtraTreeView, CTreeView)
BEGIN_MESSAGE_MAP(CExtraTreeView, CTreeView)
//{{AFX_MSG_MAP(CExtraTreeView)
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
//}}AFX_MSG_MAP
// Standard printing commands
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView construction/destruction
CExtraTreeView::CExtraTreeView()
{}
CExtraTreeView::~CExtraTreeView()
{}
void CExtraTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
// TODO: You may populate your TreeView with items by directly accessing
// its tree control through a call to GetTreeCtrl().
BuildExtraTreeView(this->m_hWnd);
}
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView message handlers
BOOL CExtraTreeView::BuildExtraTreeView(HWND hWnd)
{
HTREEITEM ht;
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Extra_DATA *node = new Extra_DATA();
node->type=TYPE_FOLDER;
node->url=TEXT("");
ht=this->GetTreeCtrl().InsertItem(TEXT("我的Extra数据"),0,0,TVI_ROOT,TVI_LAST);
this->GetTreeCtrl().SetItemData(ht,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
node = new Extra_DATA();
node->type=HTTPLINK;
node->url=TEXT("http://blog.csdn.net/huyoo");
HTREEITEM TempItem1=this->GetTreeCtrl().InsertItem("url11111111111", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem1,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
node = new Extra_DATA();
node->type=HTTPLINK;
node->url=TEXT("http://blog.csdn.net");
HTREEITEM TempItem2=this->GetTreeCtrl().InsertItem("url22222222222222", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem2,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
//url="http://blog.csdn.net/huyoo";
node->type=HTTPLINK;
node->url=TEXT("http://www.csdn.net");
HTREEITEM TempItem3=this->GetTreeCtrl().InsertItem("url333333333333333", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem3,(DWORD)node);
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
return TRUE;
}
void CExtraTreeView::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
CString aurl;
HTREEITEM Item = this->GetTreeCtrl().GetSelectedItem();
if (!Item)
return;
Extra_DATA *node = (Extra_DATA *) this->GetTreeCtrl().GetItemData(Item);
// if(node->type == TYPE_FOLDER)
// {
// return;
// }
// else
{
aurl = LPCTSTR(node->url); //这里取不到TreeCtrl中的额外数据!!!!!
}
CMainFrame * pmain=(CMainFrame*)AfxGetMainWnd();
pmain->SetWindowText(aurl);
*pResult = 0;
}
问题点数:50、回复次数:12Top
1 楼BombZhang(我当大哥很久了)回复于 2006-02-20 11:51:04 得分 10
delete node;这一句不要,因为你放到树节点的data是这个指针而不是这个指针的指向的结构,所有如果delete掉了,data装的指针也就不能访问了。
所有分配的内存应该在程序退出时统一deleteTop
2 楼csdmy(在郁闷中不停的努力)回复于 2006-02-20 13:33:02 得分 10
m_treeCtrl.InsertItem(TVIF_TEXT| TVIF_PARAM, "TREENAME"
0,
0,
0,
0, Data,
TVI_ROOT, TVI_LAST);
楼主你写插入节点的时候,第一个参数“TVIF_PARAM”必须带上才能用setdata存入数据,要不然是写不进数据的!Top
3 楼striking(庸人自扰)回复于 2006-02-20 14:05:49 得分 10
同意1楼,去除所有delete node;
在程序退出的时候, 清除treectrl结点的所有nodeTop
4 楼huyoo(空格键)回复于 2006-02-20 22:46:06 得分 0
老大们啊,最后删除node的时候,三个节点保持的数据是一样的!!
就是最后那个节点的数据!Top
5 楼simonjp(学习学习)回复于 2006-02-21 10:50:19 得分 0
你应该在处理TVN_DELETEITEM时delete nodeTop
6 楼LongLongAgoImBoy(ThereIsAMe)回复于 2006-02-21 11:12:56 得分 0
本来想用的代码试试看的,结果好像你发出来的是修改过的代码,呵呵,帮不上忙了。Top
7 楼LongLongAgoImBoy(ThereIsAMe)回复于 2006-02-21 11:16:52 得分 10
你可以先不用你自己定义的数据结构来存放额外的数据,用简单类型比如只是用数字代替,看看到底是楼上诸位说的delete node造成的问题,还是其他问题。
good luckTop
8 楼YufengShi(浪子)回复于 2006-02-21 15:45:48 得分 10
SetItemData只能存储一个32位的数,这个数由你定义,可以是int,long,甚至指针.
这和windows的消息机制很象. MSG不也有一个lParam吗,道理是一样的.
至于为什么只提供32位的存储空间,关键是控件本身不知道你要存储的数据空间
有多大, 数据的结构是什么, 所以控件没法预制分配器,
这些都是控件用户自己最了解和知道应该怎么分配数据和解读数据,通过GetItemData的
32位的数据(可能是指针,如果要存储的数据比较大).Top
9 楼huyoo(空格键)回复于 2006-02-22 09:08:56 得分 0
// ExtraTreeView.cpp : implementation of the CExtraTreeView class
//
#include "stdafx.h"
#include "Extra.h"
#include "ExtraDoc.h"
#include "ExtraTreeView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView
typedef enum tagITEM_TYPE
{
//数据类型
TYPE_FOLDER=1,TYPE_FILE
}ITEM_TYPE;
struct Extra_DATA
{
//Extra 数据
ITEM_TYPE type;
LPCTSTR url;
};
extern CExtraApp theApp;
IMPLEMENT_DYNCREATE(CExtraTreeView, CTreeView)
BEGIN_MESSAGE_MAP(CExtraTreeView, CTreeView)
//{{AFX_MSG_MAP(CExtraTreeView)
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView construction/destruction
CExtraTreeView::CExtraTreeView()
{
// TODO: add construction code here
}
CExtraTreeView::~CExtraTreeView()
{
}
BOOL CExtraTreeView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CTreeView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView drawing
void CExtraTreeView::OnDraw(CDC* pDC)
{
CExtraDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CExtraTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
// TODO: You may populate your TreeView with items by directly accessing
// its tree control through a call to GetTreeCtrl().
BuildExtraTreeView(this->m_hWnd);
}
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView printing
BOOL CExtraTreeView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CExtraTreeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CExtraTreeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView diagnostics
#ifdef _DEBUG
void CExtraTreeView::AssertValid() const
{
CTreeView::AssertValid();
}
void CExtraTreeView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
CExtraDoc* CExtraTreeView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CExtraDoc)));
return (CExtraDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CExtraTreeView message handlers
BOOL CExtraTreeView::BuildExtraTreeView(HWND hWnd)
{
HTREEITEM ht;
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Extra_DATA *node = new Extra_DATA();
node->type=TYPE_FOLDER;
node->url=TEXT("");
ht=this->GetTreeCtrl().InsertItem(TEXT("我的Extra数据"),0,0,TVI_ROOT,TVI_LAST);
this->GetTreeCtrl().SetItemData(ht,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
node = new Extra_DATA();
node->type=TYPE_FILE;
node->url=TEXT("http://blog.csdn.net/huyoo");
HTREEITEM TempItem1=this->GetTreeCtrl().InsertItem("url11111111111", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem1,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
node = new Extra_DATA();
node->type=TYPE_FILE;
node->url=TEXT("http://blog.csdn.net");
HTREEITEM TempItem2=this->GetTreeCtrl().InsertItem("url22222222222222", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem2,(DWORD)node);
delete node;
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
//url="http://blog.csdn.net/huyoo";
node->type=TYPE_FILE;
node->url=TEXT("http://www.csdn.net");
HTREEITEM TempItem3=this->GetTreeCtrl().InsertItem("url333333333333333", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem3,(DWORD)node);
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
return TRUE;
}
void CExtraTreeView::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CString aurl;
HTREEITEM Item = this->GetTreeCtrl().GetSelectedItem();
if (!Item)
return;
Extra_DATA *node = (Extra_DATA *) this->GetTreeCtrl().GetItemData(Item);
// if(node->type == TYPE_FOLDER)
// {
// return;
// }
// else
{
aurl = LPCTSTR(node->url); //这里取不到TreeCtrl中的额外数据!!!!!
}
CMainFrame * pmain=(CMainFrame*)AfxGetMainWnd();
pmain->SetWindowText(aurl);
*pResult = 0;
}
Top
10 楼huyoo(空格键)回复于 2006-02-22 09:13:09 得分 0
改成 这样 也不行,死了
BOOL CExtraTreeView::BuildExtraTreeView(HWND hWnd)
{
HTREEITEM ht;
Extra_DATA *node = new Extra_DATA();
node->type=TYPE_FOLDER;
node->url=TEXT("");
ht=this->GetTreeCtrl().InsertItem(TEXT("我的Extra数据"),0,0,TVI_ROOT,TVI_LAST);
this->GetTreeCtrl().SetItemData(ht,(DWORD)node);
//delete node;
node = new Extra_DATA();
node->type=TYPE_FILE;
node->url=TEXT("http://blog.csdn.net/huyoo");
HTREEITEM TempItem1=this->GetTreeCtrl().InsertItem("url11111111111", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem1,(DWORD)node);
//delete node;
node = new Extra_DATA();
node->type=TYPE_FILE;
node->url=TEXT("http://blog.csdn.net");
HTREEITEM TempItem2=this->GetTreeCtrl().InsertItem("url22222222222222", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem2,(DWORD)node);
//delete node;
//url="http://blog.csdn.net/huyoo";
node->type=TYPE_FILE;
node->url=TEXT("http://www.csdn.net");
HTREEITEM TempItem3=this->GetTreeCtrl().InsertItem("url333333333333333", ht, TVI_LAST);
this->GetTreeCtrl().SetItemData(TempItem3,(DWORD)node);
delete node;
return TRUE;
}Top
11 楼huyoo(空格键)回复于 2006-02-22 09:22:46 得分 0
我本来只是想做一个RSS的树的,没有想到treectrl的item保持个数据都这样麻烦,看来是做不了了Top
12 楼CPP2008()回复于 2006-05-31 17:55:33 得分 0
搜索到这个帖子。
其实可以选用其他的方法。
建立一个索引。
struct tagExData
{
int D1;
int D2;
int D3;
};
tagExData Index_[100];
当你 SetItemData(h, index)的时候,只是把 这个全局Index_ 的 index 存进去了。
当你 index = GetItemData(h)的时候,得到的是 这个全局Index_ 的 index。
当然这个这个全局Index_必须你自己初始化。
看看是否有帮助。如果有后来的人看到这个帖子。Top
相关问题
- CTreeCtrl 如何用SetItemData使Item保持额外数据?
- 初級問題 關于CTreeCtrl::SetItemData()設置相關32位值?
- 急啊!CTreeCtrl中的SetItemData和GetItemData怎么用?
- 请问CTreeCtrl控件的SetItemData能不能设置一个字符串?(在线等)
- 如何让CTreeCtrl里的Item有连线?
- CTreeCtrl中插入ITEM的问题
- 请问CTreeCtrl的SetItemData函数能否保存一个结构体?应该如何保存?
- 往CTreeCtrl的父Item上插入子Item的问题!!
- CTreeCtrl中怎样得到鼠标右键所点的Item???
- 如何得到CTreeCtrl添加ITEM时设置的item.lParam?




