CTreeCtrl 如何用SetItemData使Item保持额外数据?

糊糊 2006-02-20 11:18:45
主  题: 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;

}
...全文
469 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
CPP2008 2006-05-31
  • 打赏
  • 举报
回复
搜索到这个帖子。

其实可以选用其他的方法。
建立一个索引。

struct tagExData
{
int D1;
int D2;
int D3;
};

tagExData Index_[100];

当你 SetItemData(h, index)的时候,只是把 这个全局Index_ 的 index 存进去了。
当你 index = GetItemData(h)的时候,得到的是 这个全局Index_ 的 index。

当然这个这个全局Index_必须你自己初始化。

看看是否有帮助。如果有后来的人看到这个帖子。
糊糊 2006-02-22
  • 打赏
  • 举报
回复
我本来只是想做一个RSS的树的,没有想到treectrl的item保持个数据都这样麻烦,看来是做不了了
糊糊 2006-02-22
  • 打赏
  • 举报
回复
改成 这样 也不行,死了
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;

}
糊糊 2006-02-22
  • 打赏
  • 举报
回复
// 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;
}
Jimmy_Xia 2006-02-21
  • 打赏
  • 举报
回复
你可以先不用你自己定义的数据结构来存放额外的数据,用简单类型比如只是用数字代替,看看到底是楼上诸位说的delete node造成的问题,还是其他问题。
good luck
Jimmy_Xia 2006-02-21
  • 打赏
  • 举报
回复
本来想用的代码试试看的,结果好像你发出来的是修改过的代码,呵呵,帮不上忙了。
simonjp 2006-02-21
  • 打赏
  • 举报
回复
你应该在处理TVN_DELETEITEM时delete node
YufengShi 2006-02-21
  • 打赏
  • 举报
回复
SetItemData只能存储一个32位的数,这个数由你定义,可以是int,long,甚至指针.
这和windows的消息机制很象. MSG不也有一个lParam吗,道理是一样的.
至于为什么只提供32位的存储空间,关键是控件本身不知道你要存储的数据空间
有多大, 数据的结构是什么, 所以控件没法预制分配器,
这些都是控件用户自己最了解和知道应该怎么分配数据和解读数据,通过GetItemData的
32位的数据(可能是指针,如果要存储的数据比较大).
BombZhang 2006-02-20
  • 打赏
  • 举报
回复
delete node;这一句不要,因为你放到树节点的data是这个指针而不是这个指针的指向的结构,所有如果delete掉了,data装的指针也就不能访问了。

所有分配的内存应该在程序退出时统一delete
糊糊 2006-02-20
  • 打赏
  • 举报
回复
老大们啊,最后删除node的时候,三个节点保持的数据是一样的!!
就是最后那个节点的数据!
striking 2006-02-20
  • 打赏
  • 举报
回复
同意1楼,去除所有delete node;

在程序退出的时候, 清除treectrl结点的所有node
csdmy 2006-02-20
  • 打赏
  • 举报
回复
m_treeCtrl.InsertItem(TVIF_TEXT| TVIF_PARAM, "TREENAME"
0,
0,
0,
0, Data,
TVI_ROOT, TVI_LAST);
楼主你写插入节点的时候,第一个参数“TVIF_PARAM”必须带上才能用setdata存入数据,要不然是写不进数据的!

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧