ttreenode.data的问题(50分)

  • 主题发起人 主题发起人 fu_xiang_yu
  • 开始时间 开始时间
F

fu_xiang_yu

Unregistered / Unconfirmed
GUEST, unregistred user!
ttreeview.addchildobject(node:ttreenode; s:string; ptr:pointer)

假设 anothernode:ttreenode; s:string; ptrfirst,ptrsecond:string;
firstnode:=treeview.addchildobject(anothernode,s,pchar(ptrfirst));
secondnode:=treeview.addchildobject(..., ..., pchar(ptrsecond));
那么onenode.data又代表什么,是pchar(ptrfirst)吗?

在同一个procedure里调用firstnode.data好像是对的
但在不同procedure里调用firstnode.data值却变成了pchar(ptrsecond)
怎么回事?
 
怎么没人呀
我知道我说得太抽象了,没办法只好硬着头皮贴出代码
不过它实在是太乱太白痴了,看过请不要笑我

另:如果彻底解决了这问题,再加50分

procedure TForm1.FormCreate(Sender: TObject);
var dri:integer; captionpath:pchar; nodeadded:ttreenode;
begin
for dri:=65 to 90 do
begin
if getdrivetype(pchar(chr(dri)+':/')) in [3..4]
then begin
captionpath:=pchar(string(chr(dri)+':'));
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',captionpath);
nodeadded.HasChildren:=true;
listview1.Items.Add.caption:=chr(dri)+':';
end;
end;
listview1.Items[0].Selected:=true;// 如果在此showmessage(captionpath),得到结果是正确的
end;//这段程序将固定驱动器和网络驱动器加到treeview1里面

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
nodetext,path,entirename:string;
found:integer;
searchrec:tsearchrec;
node,nodewhichisadd,nodeexam:ttreenode;
clearedlist:boolean;
begin
clearedlist:=false; //刚开始还没有clear过
node:=treeview1.selected; //设置node为当前选择的节点
nodetext:=treeview1.selected.Text; //设置nodetext为当前节点的显示文本
nodeexam:=node;
while nodeexam.parent<>nil do nodeexam:=nodeexam.Parent; //防止非本机节点执行事件
if ((nodetext<>'我的电脑') and (not node.expanded) and (nodeexam.text='我的电脑')) then
begin
path:=pchar(node.data)+'/*.*'; //查找对象为当前节点下的所有文件
showmessage(pchar(node.data));//这里出现了问题,如果双击c:,showmessage
//的内容是'd:',双击d:,则showmessage的是'e:',但刚才在formcreate里
//showmesssage都是正确的呀!!!!!!!!!
found:=findfirst(path,faanyfile,searchrec);//查找第一个文件
while found=0 do
begin
if ((searchrec.attr=fadirectory) and (searchrec.name<>'.') and (searchrec.name<>'..')) then
begin
if node.parent.text<>'我的电脑' //设置entirename为当前找到节点绝对路径名
then entirename:=pchar(node.data)+'/'+searchrec.Name; {showmessage(node.Text); }
nodewhichisadd:=treeview1.Items.AddChildObject(node,searchrec.name,pchar(entirename));
//加到当前节点下
nodewhichisadd.HasChildren:=true; //使每个节点前都有+号
if not clearedlist then //判断listview是否clear过了
begin
listview1.Items.BeginUpdate;
listview1.items.Clear;
clearedlist:=true;
listview1.items.EndUpdate;
end;
listview1.Items.Add.caption:=searchrec.name;
end
else begin //如果不是目录文件(是其他文件)则只加到listview下
if not clearedlist then
begin
listview1.items.Clear;
clearedlist:=true;
end;
listview1.Items.Add.caption:=searchrec.name;//加到listview下
end;
found:=findnext(searchrec);
end;
findclose(searchrec);
end;
node.expand(false); //双击时将展示下级节点
end;

程序很差劲,让大家见笑了

写的这么乱,不知大家看懂了没:(
 
不用pchar用指针
 
怎么用,鉴于我是大菜鸟,能不能说清楚一点
这个问题已经困扰我一个多星期了,如能真正
帮我解决,我再出50大洋
 
firstnode:=treeview.addchildobject(anothernode,s,pchar(ptrfirst));
改成
firstnode:=treeview.addchildobject(anothernode,s,@ptrfirst);
试试看
 
那以下这段的captionpath该怎么写
写成captionpath:=@(string(chr(dri)+':')) ?
captionpath设为pointer型的话,运行时提醒缺参数

原码:
captionpath:=pchar(string(chr(dri)+':'));
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',captionpath);
 
重新定义一个变量a
a:=chr(dri)+':';
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',@a);
就行了。
我觉得你还没有理解
函数
ttreeview.addchildobject(node:ttreenode; s:string; ptr:pointer)
里面的ptr的含义,它是一个指针类型,指向该节点包含的数据。
所以该节点的数据的内存必须已经分配,比如a:string。---------ptr<<=====@a
或者一个对象a:TObject;a:=Tobjcet.create...prt<<=============a
懂了吗?

 
//我的感觉是
procedure TForm1.FormCreate(Sender: TObject);
var dri:integer; captionpath:pchar; nodeadded:ttreenode;
begin
for dri:=65 to 90 do
begin
if getdrivetype(pchar(chr(dri)+':/')) in [3..4]
then begin
///
New(CaptionPath);
///
captionpath:=pchar(string(chr(dri)+':'));
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',captionpath);
nodeadded.HasChildren:=true;
listview1.Items.Add.caption:=chr(dri)+':';
end;
end;
listview1.Items[0].Selected:=true;// 如果在此showmessage(captionpath),得到结果是正确的
end;//这段程序将固定驱动器和网络驱动器加到treeview1里面
//另外在删除节点时不要忘记释放CaptionPath所使用的内存
 
我还是没有弄懂以下两个东西:
如过treeview.addchildobject(onenode,s,ptr);
执行这句以后ptr和onenode.data到底是什么关系
 
ptr = pointer(onenode.data);
或者说:
onenode.data = integer(ptr);
你的程序其实有很大的问题:
captionpath:=pchar(string(chr(dri)+':'));
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',captionpath)
这里,你把captionpath作为pointer在使用,可以,但是,这个pchar
是临时分配的,一旦出了这个procedure,都要收回的。这样,等你下次想要调用的时候,
其实,onenode.data保存的指针已经不知道指向什么地方了。

最好:
type
PSavedRecord = ^TSavedRecord;
TSavedRecord = record
CaptionPath:String;
...//其它你想保存的信息。
end;

captionpath:=pchar(string(chr(dri)+':'));
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',captionpath)
改成:
psv1:PSavedRecord;
new(psv1);
psv1.CaptionPath := string(chr(dri)+':');
nodeadded:=treeview1.Items.AddChildobject(treeview1.items[0],chr(dri)+':',psv1);
注意,在释放TreeView的Items时,要释放这些new的内存。


 
解决了,谢谢几位
 
多人接受答案了。
 
后退
顶部