TreeView上的节点连同其关联的对象的保存

I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
保存对象要稍难一些,因为在TreeNode中只存了个指针,除非TreeNode.Data是一个能用流操作的对象。如果是这样:(简单示范)
var
s1: TFileStream;
s2: TMemoryStream;
nCount, i: Inteter;
 
procedure CopyStream( sSrc, sDest: TStream );
begin
nCount := sSrc.Size;
sDest.Write( nCount, sizeof(nCount) ); // 请写入字节数
sDest.CopyFrom( sSrc, 0 ); // 写入TreeView的内容,第二个参数为0表示全部复制
sSrc.Size := 0; // 清掉以前数据
end;
 
begin
s2 := TMemoryStream.Create;
// 保存到文件
s1 := TFileStream.Create( '文件名', fmCreate );
TreeView.SaveToStream( s2 );
CopyStream( s2, s1 );
// 下面写入TreeNode的Data
for i:=0 to TreeView.Items.Count-1 do
begin
if Assigned(TreeView.Items.Data) then
begin
s2.Write( i, sizeof(i) ); // 保存序号,如果你有更好标识方法,可以代替
TYourDataClass(TreeView.Items.Data).SaveToStream( s2 ); // TYourDataClass只是假定的名字
CopyStream( s2, s1 );
end;
end;
 
s1.Free; // 在Free之前它会保存的
 
// 从文件读取
s1 := TFileStream.Create( '文件名', fmOpenRead );
s1.ReadBuffer( nCount, sizeof(nCount) );
s2.CopyFrom( s1, nCount );
TreeView.LoadFromStream( s2 );
// 下面读入TreeNode的Data
while s1.Position<s1.Size do
begin
s1.ReadBuffer( i, sizeof(i) );
s1.ReadBuffer( nCount, sizeof(nCount) );
s2.CopyFrom( s1, nCount );
TreeView.Items.Data := TYourDataClass.Create; // 当然,可能Create调用格式是另外的
TYourDataClass(TreeView.Items.Data).LoadFromStream( s2 );
end;
s1.Free;
 
s2.Free;
 
这个例子不一定能满足你的要求,不过至少你可以参考一下。因为在你的程序里,可能TreeView.Items.Data还有别的变量指着。但你可以变化一下。比如倒着赋值。
******************
我曾经这样来记录我的TREEVIEW,不知道和你的想法是否一致:
{伪代码}
{假设表中有一个TREEVIEW,这里定义一个结构做为节点关联的DATA}
type PitemData=^TItemData;
TItemData=record
caption:string;
data:integer;
end;
----------------------------------------
建树的过程:
循环:
新建一个PITEMDATA的指针,
为指针的域赋值,
新建一个节点,
节点的DATA=新指针,
保存文件的过程:
创建一个新文件:
得到当前树节点的最顶层节点数,向文件中写节点数,开始循环节点数,遍历每个节点
然后向文件中分别写入是否有子节点,有多少个子节点,每个节点下指针的数据.根据层次的增加可能会使用递归(类似于读目录树一样)将所有数据写入文件.
------------------------------------
导入文件的过程:
打开相应文件,
依照上面保存的方法得到树结构节点数,然后使用导入数的过程,为它们分配指针,填充适当的数据.
记住:在程序退出时,要记得释放为每一个节点分配的指针.其实这个做法和TREEVIEW的SAVETOFILE差不多,但是是以二进制保存,而且相当于使用一个自己定义结构的数据表.
这个虽然不是依照上面意思所做的工作,但是有些类似.
他简单在层次固定,数据格式固定,但是如果要修改,照上面的结构也很容易,如果你愿意告诉我你想记录你的什么样的树图,我可以写源码给你.
//这一段是把文件读出,形成树
procedure TForm1.Button3Click(Sender: TObject);
Var
F:Integer;
i,j:integer;
CurrentNode:TTreeNode;
ChildNode:TTreeNode;
ChildCount:integer;
Nowx,Nowy:integer;
begin
TreeView1.Items.Clear
F:=FileOpen('main.RGN',fmOpenRead);
if F<0 then exit;
FileRead(F,RegionCount,sizeof(integer));
for i:=1 to RegionCount do begin
FileRead(F,childcount,sizeof(integer));
//这一段是记录树的数据.
procedure TForm1.Button2Click(Sender: TObject);
Var
F:Integer;
i,j:integer;
CurrentNode:TTreeNode;
ChildNode:TTreeNode;
ChildCount:integer;
begin
F:=FileCreate('main.RGN');
if F<0 then exit;
Filewrite(F,RegionCount,sizeof(integer));
CurrentNode:=TreeView1.Items.GetFirstNode;
for i:=1 to RegionCount do begin
Childcount:=currentNode.Count
Filewrite(F,ChildCount,sizeof(integer));
FileWrite(F,PPoint(CurrentNode.data)^.x,sizeof(integer));
FileWrite(F,PPoint(CurrentNode.data)^.y,sizeof(integer));
ChildNode:=CurrentNode.getFirstChild
for j:=0 to CurrentNode.Count-1 do begin
fileWrite(F,PPoint(ChildNode.data)^.x,sizeof(integer));
FileWrite(F,PPoint(ChildNode.data)^.y,sizeof(integer));
ChildNode:=childNode.getNextSibling;
end;
CurrentNode:=CurrentNode.getNextSibling
end;
FileClose(F);
end;
Fileread(F,Nowx,sizeof(integer));
FileRead(F,Nowy,sizeof(integer));
CurrentNode:=TreeView1.Items.Add(nil,format('x:%d,y:%d',[Nowx,nowy]));
for j:=0 to ChildCount-1 do begin
Fileread(F,Nowx,sizeof(integer));
FileRead(F,Nowy,sizeof(integer));
childNode:=TreeView1.items.Addchild(CurrentNode,format('x:%d,y:%d',[Nowx,nowy]));
end;
end;
FileClose(F);
end;
 
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
636
import
I
顶部