我的数据形如下,不用显示,只是在后台处理,
curPolTree|----Fields1
|---Strings1
|---Strings2....
.........
|----Fields2于是我想到用树结构来操作,想借用vcl中的TTreeNodes对象,但是不成功。主要有如下问题:
1、PolData := TTreeNodes.create(nil);//这里创建时必须传入他的owner值,这个值//必须是TreeView的父类,由于我没有他的父类,就写入nil
2、PolData.Add(nil,tmpStr);//由于是要创建根结点,所以这里要写入nil。但在这里就运行出错。我跟踪vcl源码发现如下代码:
if Node = nil then
Result := Owner.CreateNode
else
Result := Node;
也就是说,如果你在加入节点时传入的父节点为nil,那么由它的所有者自动创建一个Node。但是,我在创建PolData时是没有指定Owner的,这时它去访问它的Owner,就出现内存非法访问。如果我在创建PolData时,指定Owner为某TreeView,那么这个poldata中的数据就与那个TreeView中的一样了,那还不如直接用一个TreeView,只是把它的Visable设为false就行了。但用一个TreeView会有不少的内存开支,并且我并不需要显示这些数据。我说的这么详细,是因为我花了一些时间来解决这个问题,有别于那些没有丁点钻研精神的CSDNer。所以希望能得到大家的帮助。请问:还没有没有其它比较好用的、可靠的Tree数据结构可以用?
curPolTree|----Fields1
|---Strings1
|---Strings2....
.........
|----Fields2于是我想到用树结构来操作,想借用vcl中的TTreeNodes对象,但是不成功。主要有如下问题:
1、PolData := TTreeNodes.create(nil);//这里创建时必须传入他的owner值,这个值//必须是TreeView的父类,由于我没有他的父类,就写入nil
2、PolData.Add(nil,tmpStr);//由于是要创建根结点,所以这里要写入nil。但在这里就运行出错。我跟踪vcl源码发现如下代码:
if Node = nil then
Result := Owner.CreateNode
else
Result := Node;
也就是说,如果你在加入节点时传入的父节点为nil,那么由它的所有者自动创建一个Node。但是,我在创建PolData时是没有指定Owner的,这时它去访问它的Owner,就出现内存非法访问。如果我在创建PolData时,指定Owner为某TreeView,那么这个poldata中的数据就与那个TreeView中的一样了,那还不如直接用一个TreeView,只是把它的Visable设为false就行了。但用一个TreeView会有不少的内存开支,并且我并不需要显示这些数据。我说的这么详细,是因为我花了一些时间来解决这个问题,有别于那些没有丁点钻研精神的CSDNer。所以希望能得到大家的帮助。请问:还没有没有其它比较好用的、可靠的Tree数据结构可以用?
其实也不难。
定义一个节点类,几个属性,几个操作方法即可:)
不过你的名字有点.............
想法不错,不过一是对XML不熟悉,二是如果用xml,会代来额外的内存开销,我的数据处理要求实时、长期的运行,没有试过怕有问题。
xml我先看看再说。xml格式的数据将来是一定要支持的。to:hfyun(逮住就问)
当然了,实在不行就不能偷懒了,只能自己写了。不过,我觉得在Delphi下面也应该像C++一样,有现成的Tree数据结构可以用,如SGI看上版体的STL和Boost库。并不是说,正是有了这些现成的东东,把程序员搞的越来越懒了,而在在一定的条件下,自己写一个这样的库嚎时、效率不一定高。所以才出些下策。希望大家再能提供点线索。
TMap = Record
fIndex: Integer;
fName: String;
fCode: string;
fType: Integer;
fDate: TDate;
fFileType:String;
FileName: string;
fRe: string;
end;{***************************************************************
* 方 法 名 : TfrmMap.AddRootNode
* 编写目的 :
* 作 者 : 黄仁光
* 参 数 : MapType:Integer
* 结 果 : TTreeNode
* 编写日期 :2002年12月18日
****************************************************************}
function TfrmMap.AddRootNode(MapType:Integer):TTreeNode;
var
RootNode:TTreeNode;
begin
treImage.Items.Clear;
case MapType of
0://单位方位图
begin
RootNode := treImage.Items.Add(nil,'单位方位图');
end;
1://建筑平面图
begin
RootNode := treImage.Items.Add(nil,'建筑平面图');
end;
2://建筑立面图
begin
RootNode := treImage.Items.Add(nil,'建筑立面图');
end;
3://楼层平面图
begin
RootNode := treImage.Items.Add(nil,'楼层平面图');
end;
4://消防部署图
begin
RootNode := treImage.Items.Add(nil,'消防部署图');
end;
5://最佳路径图
begin
RootNode := treImage.Items.Add(nil,'最佳路径图');
end;
end;
Result := RootNode;
end;{***************************************************************
* 方 法 名 : TfrmMap.AddChildNode
* 编写目的 :
* 作 者 : 黄仁光
* 参 数 : RootNode:TTreeNode;fIndex:Integer;fCode,fName:String;FileName:String
* 结 果 : None
* 编写日期 :2002年12月18日
****************************************************************}
procedure TfrmMap.AddChildNode(RootNode:TTreeNode;fIndex:Integer;fCode,fName:String;fType:Integer;FileName:String);
var
ChildNode:TTreeNode;
pMapChild:PMapNode;
begin
new(pMapChild);
pMapChild^.fIndex := fIndex;
pMapChild^.fCode := fCode;
pMapChild^.fName := fName;
pMapChild^.fType := fType;
pMapChild^.FileName := FileName;
ChildNode := treImage.Items.AddChildObject(RootNode,fCode,pMapChild);
end;procedure TfrmMap.treImageClick(Sender: TObject);
var
SelectNode:TTreeNode;
pMapChild:PMapNode;
fIndex:Integer;
FileName:String;
begin
try
new(pMapChild);
SelectNode := treImage.Selected;
SelectNode.Expanded := true;
try
if SelectNode.Level = 1 then
begin
Screen.Cursor := crHourGlass;
pMapChild := PMapNode(SelectNode.Data); MapEntryMode := 1;//如果选择树里面的图片,说明图片表是编辑
FileName := pMapChild^.FileName;
MapFileName := FileName;
MapIndex := pMapChild^.fIndex;
MapCode := pMapChild^.fCode; /////////////////////
p_PicType := pMapChild.fType;//取得图片的类型 if FileName <> OldFileName then
begin
fIndex := pMapChild^.fIndex;
ShowMapRS(fIndex);
oldFileName := FileName;
end;
end;
except
Screen.Cursor := crDefault;
Exit;
end;
finally
Screen.Cursor := crDefault;
end;
end;
注意在删除Node时一定要释放占用的内存。
这里的treImage说穿了还是一个TreeView(如果不是请你说明是什么),还是离不开我在前面说了不用的TreeView。我就是只想用TreeNodes来保存数据,不用任何TreeView。(treImage.Items其实就是TreeNodes)2、你的代码中临时对像的问题:(比较严重)
procedure TfrmMap.AddChildNodeFileName:String);
var
ChildNode:TTreeNode;
pMapChild:PMapNode;
begin
new(pMapChild);
//这里生成了一个生存周期只在这个procedure内有效的pMapChild,你用这个
//临时的指针保存了数据(加一个节点),离开了这个作用域,对象自动被释放
//Node.Data保存的只是一个被释放掉的指针。有问题啊??
pMapChild^.fIndex := fIndex;
......
end;
单纯的向树里加Node和Data我还是会的,请各位看清我的问题再作答。我是想问还有没有现成的数据结构可以用?另外,看了一下午的xml,有点意思了,我的程序中将来是要支持xml的,不如现在就以xml为基础,把原来的data转成xml再处理,这样以后就是单一的数据接口。(越想越爽!)