(我要说清楚)如何将TreeView上的节点连同其关联的对象存在一个文件里并可以重新装载访问。

forever 2000-01-11 01:17:00
主  题:如何将TreeView上的节点连同其关联的对象存在一个文件里并可以重新装载访问。

我必须把问题说清楚;
type
PResNodeRec = ^TResNodeRec;
TResNodeRec = record
ID: Integer;
Name: string[64];
Flag: SmallInt;
Prop: SmallInt;
end;

procedure AddLogicNode(ATV: TTreeView);
var
resNodeRec: PResNodeRec;
begin
with ATV do
begin
New(resNodeRec);
with resNodeRec^ do
begin
ID := 555;
Name := '新建对象';
Flag := 0;
Prop := 1;
end;
Items.AddChildObject(Selected, resNodeRec.recName, resNodeRec);
SaveTV(ATV);
end;

procedure SaveTV(aTV: TTreeView);
var
strmResExp: TEncodeStream;
begin
if FileExists('ResExp.nod') then strmResExp := TEncodeStream.Create('ResExp.nod', fmOpenWrite)
else strmResExp := TEncodeStream.Create('ResExp.nod', fmOpenWrite or fmCreate);
try
aTV.SaveToStream(strmResExp);
finally
strmResExp.Free;
end;
end;

//Unit EncodeStream
//---------------------------可进行解码、编码的文件流----------------------
type
TEncodeStream = Class (TFileStream)
private
FKey: Char;
public
constructor Create(const FileName: string; Mode: Word);
function Read(var Buffer; Count: LongInt): LongInt; override;
function Write(const Buffer; Count: LongInt): LongInt; override;
property Key: Char read FKey write FKey default 'A';
end;
//---------------------------------------------------------------------

implementation

constructor TEncodeStream.Create(const FileName: string; Mode: Word);
begin
inherited Create(FileName, Mode);
FKey := 'A';
end;

function TEncodeStream.Read(var Buffer; Count: LongInt): LongInt;
var
pBuf, PEnc: PChar;
I, CountRead, EncVal: Integer;
begin
GetMem(PEnc, Count);
try
CountRead := inherited Read(PEnc^, Count);
pBuf := PChar(@Buffer);
for I := 0 to CountRead - 1 do
begin
EncVal := (Ord(pEnc[I]) - Ord(Key)) mod 256;
pBuf[I] := Chr(Encval);
end;
finally
FreeMem(PEnc, Count)
end;
end;

function TEncodeStream.Write(const Buffer; Count: LongInt): LongInt;
var
pBuf, PEnc: PChar;
I, EncVal: Integer;
begin
GetMem(pEnc, Count);
try
pBuf := PChar(@Buffer);
for I := 0 to Count - 1 do
begin
EncVal := (Ord(pBuf[I]) + Ord(Key)) mod 256;
pEnc[I] := Chr(EncVal);
end;
Result := inherited Write(pEnc^, Count);
finally
FreeMem(pEnc, Count);
end;
end;

end.

我只所以要把树上信息写到一个加了密的文件里而不是写到数据库里
(哪怕是dbf或Db或mdb),原因是我想让我的程序尽量的小,不需要数据访问链路支持。

我想写总是可以写的甚至可以按顺序写到多个文件里,但是怎样才能再组装回来,并把树上节点对应信息一一挂上!

SaveToFile我最先就是用它的,但它只能保存树上节点的标题而已。

...全文
195 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
pipimei 2000-01-12
  • 打赏
  • 举报
回复
我是这样处理的;(思路)
将treeview的内容(标题和其data)以流的方式保存到一个文件。该文件结构分两部分:
1、视图部分,即treeview的标题和结构,并写入其总长度;
2、数据部分,即treeview的Object;
装载时,找到视图的长度,按视图的长度读入视图结构和标题,再依次读入各个Node的数据。
Venne 2000-01-11
  • 打赏
  • 举报
回复
不好意思,在你刚才的问题里,因为网络缘故我的文章发了三次,现在看你的代码,我想我们差别不太大,我的做法和你的区别在于你每次加入对象,我通常是将你的PresNodeRec指针赋给节点的DATA属性,DATA可以保存一个指针,当然结构指针也一样,我是这样来操作树的。下面我再发一次我的看法:
我曾经这样来记录我的TREEVIEW,不知道和你的想法是否一致:
{伪代码}
{假设表中有一个TREEVIEW,这里定义一个结构做为节点关联的DATA}
type PitemData=^TItemData;
TItemData=record
caption:string;
data:integer;
end;
----------------------------------------
建树的过程:
循环:
新建一个PITEMDATA的指针,
为指针的域赋值,
新建一个节点,
节点的DATA=新指针,

保存文件的过程:
创建一个新文件:
得到当前树节点的最顶层节点数,向文件中写节点数,开始循环节点数,遍历每个节点
然后向文件中分别写入是否有子节点,有多少个子节点,每个节点下指针的数据.根据层次的增加可能会使用递归(类似于读目录树一样)将所有数据写入文件.

------------------------------------
导入文件的过程:
打开相应文件,
依照上面保存的方法得到树结构节点数,然后使用导入数的过程,为它们分配指针,填充适当的数据.

记住:在程序退出时,要记得释放为每一个节点分配的指针.其实这个做法和TREEVIEW的SAVETOFILE差不多,但是是以二进制保存,而且相当于使用一个自己定义结构的数据表.

这个虽然不是依照上面意思所做的工作,但是有些类似.
他简单在层次固定,数据格式固定,但是如果要修改,照上面的结构也很容易,如果你愿意告诉我你想记录你的什么样的树图,我可以写源码给你.

kxy 2000-01-11
  • 打赏
  • 举报
回复
SaveToFile我最先就是用它的,但它只能保存树上节点的标题而已。

是的,SaveToFile不能保存Object,包括TStringList,Tstrings等等都是这样.
自己处理吧,应该没有难度.

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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