我在写一个管理方面的东东,要用到在一个PageControl中的不同页中建立不同内容的树,从数据库中取数据建立树。数据库如下结构:
AreaID Area1 Area2 Area3 Area4 Area5 PageName
1 XX集团 山东地区 济南 青岛 XXX CES
2 XX集团 上海地区 上海 浦东 ZZZ CES
3 XX集团 北京地区 北京 大兴 BBB CES
4 我的邮箱 收件箱 Mail
5 我的邮箱 发件箱 Mail这种数据库结构可以方便整个需要建立树的数据统一存放在一个库中,树的建立我已经完成,单个建立也没有问题,但是在两个不同的PAGE切换的时候出现问题,如下:Project ProjCES.exe raised exception class EAccessViolation with message 'Access violation at address 004AF13E in module 'ProjCES.exe'.read of address 00000000 process stopped.感觉应该是建树的指针没有释放造成的,但是一直没有找到原因。
我的目的是在一个PageControl的不同页中建立不同的树,从一个数据库中取数据
请大家帮忙看一下,付原码如下:
type
//定义指针记录,用来建立树节点
PCurNode=^TCurNode;
TCurNode=record
RelatedInfo:string; //节点显示的文本
keyName:string; //节点的关键值,唯一的
ParentName:string; //父节点KEY值
lev:integer; //记录本节点在数据库中的级别end;//1、 树的建立函数
function CreateTree(Treevw:TTreeview;strPageName:string):boolean;
var
ParentNode,CurNode:TTreeNode; //节点
NodeTxt,key:string; //节点文本显示内容
ParentTxt:String; //用来判断是否有相同的字段值存在 ,参照变量
aNode: PCurNode; //指针型
i:integer;
// NodeTxtCache:array[1..5] of string; //记录第一个记录的所有字段值。
begin
//把树视图清空
Treevw.Items.BeginUpdate; //树开始更新
Treevw.Items.Clear; //清空树
with fmCESMainForm.qryAreaTable do
begin Close;
SQL.Clear;
if trim(strPageName)='CES' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="CES";'
else if trim(strPageName)='Mail' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="Mail";'
else if trim(strPageName)='Address' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="Address";'; Prepare;
Open;
First; while not eof do
begin
key:='root'; //根节点的 keyName是root for i:=1 to 5 do //从数据库的第1个字段到第5 字段依次处理
begin
ParentTxt:=key; //第一个字段为根节点节点,设置keyName为root //取字段值
NodeTxt:=Trim(FieldbyName('Area'+IntTostr(i)).asstring);
if NodeTxt=null then break; //如果内容为空此跳到下一记录 //节点的keyName值为第1节点+第二节点+第3节点...。如第1个字段'root'
//第二个为'root字段1' 第三个为'root字段1字段2'
key:=Trim(ParentTxt+NodeTxt);
//将ParentNode当成一个临时变量来用,查找有没有相同KeyName的节点
//如有则跳过
ParentNode:=FindParent(Treevw,key);
if ParentNode<>nil then
begin
continue; //有相同KeyName的节点则跳过这一字段
end; ParentNode:=FindParent(Treevw,ParentTxt); //查找父节点
New(aNode); //定义新的节点指针
aNode.RelatedInfo:=NodeTxt; //节点显示文本
aNode.keyName:=key; // 节点的关键值
aNode.ParentName:=ParentTxt; //父节点的关键值
aNode.lev:=i-1; // 节点的级别
if (ParentNode<>nil) and (i<>1) then
begin
CurNode:=Treevw.Items.AddChildObject(ParentNode,NodeTxt,aNode); end
else begin //如果没有父节点并且是第1条记录,则建立根节点 CurNode:=Treevw.Items.AddObjectFirst(ParentNode,NodeTxt,aNode);
end; CurNode.SelectedIndex:=1; end;{for} Next; end; {while}
close;
Free;
end;{with } Treevw.Items.EndUpdate;
result:=true;
end;//寻找父节点
function FindParent(TreeVw:TTreeview;idx:string):TTreeNode;
var
i:integer;
begin
result:=nil; for i:=0 to TreeVw.Items.Count-1 do
begin
if PCurNode(TreeVw.Items.Item[i].Data)^.keyName=idx then
begin
//showmessage( PCurNode(Treevw.Items.Item[i].Data)^.ParentName+' '+idx+'in findParent');
result:=TreeVw.Items.Item[i];
break;
end;
end;
end;
/////////////////////////////////
//第一个页,建立树时没有问题。建立完成后切换到别的页再切回时出问题。
procedure TfmCESMainForm.tsCESManagerShow(Sender: TObject);begin CreateTree(tvCES,'CES');
end; {procedure }
///////////////////////////////
//第二页,procedure TfmCESMainForm.tsMailShow(Sender: TObject);
begin
// CreateTree(tvMail,'Mail'); //加上此语句时出现问题。
end;//////////////////////////////
//主窗建立一个树时切换也不会有问题,但只是建两个就出现了问题。
procedure TfmCESMainForm.FormCreate(Sender: TObject);
//var
// strPageName:string;
begin
//try
//strPageName:='CES';
//CreateTree(tvCES,strPageName);
// strPageName:='Mail';
//CreateTree(tvMail,strPageName);
// except
// close;//CreateTree(tvAddress);
// end;
end;
/////////////////////////////
//下面都是我想释放内存的,但是都不行,解决不了问题。
procedure TfmCESMainForm.tvCESDeletion(Sender: TObject; Node: TTreeNode);
begin
//ClearTree(tvCES);
dispose(PCurNode(node.data));
end;procedure TfmCESMainForm.tvMailDeletion(Sender: TObject; Node: TTreeNode);
begin
//ClearTree(tvMail);
dispose(PCurNode(node.data));
end;procedure TfmCESMainForm.tsCESManagerHide(Sender: TObject);
begin
//ClearTree(tvCES);
end;procedure TfmCESMainForm.tsMailHide(Sender: TObject);
begin
// ClearTree(tvMail);
end;end.
AreaID Area1 Area2 Area3 Area4 Area5 PageName
1 XX集团 山东地区 济南 青岛 XXX CES
2 XX集团 上海地区 上海 浦东 ZZZ CES
3 XX集团 北京地区 北京 大兴 BBB CES
4 我的邮箱 收件箱 Mail
5 我的邮箱 发件箱 Mail这种数据库结构可以方便整个需要建立树的数据统一存放在一个库中,树的建立我已经完成,单个建立也没有问题,但是在两个不同的PAGE切换的时候出现问题,如下:Project ProjCES.exe raised exception class EAccessViolation with message 'Access violation at address 004AF13E in module 'ProjCES.exe'.read of address 00000000 process stopped.感觉应该是建树的指针没有释放造成的,但是一直没有找到原因。
我的目的是在一个PageControl的不同页中建立不同的树,从一个数据库中取数据
请大家帮忙看一下,付原码如下:
type
//定义指针记录,用来建立树节点
PCurNode=^TCurNode;
TCurNode=record
RelatedInfo:string; //节点显示的文本
keyName:string; //节点的关键值,唯一的
ParentName:string; //父节点KEY值
lev:integer; //记录本节点在数据库中的级别end;//1、 树的建立函数
function CreateTree(Treevw:TTreeview;strPageName:string):boolean;
var
ParentNode,CurNode:TTreeNode; //节点
NodeTxt,key:string; //节点文本显示内容
ParentTxt:String; //用来判断是否有相同的字段值存在 ,参照变量
aNode: PCurNode; //指针型
i:integer;
// NodeTxtCache:array[1..5] of string; //记录第一个记录的所有字段值。
begin
//把树视图清空
Treevw.Items.BeginUpdate; //树开始更新
Treevw.Items.Clear; //清空树
with fmCESMainForm.qryAreaTable do
begin Close;
SQL.Clear;
if trim(strPageName)='CES' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="CES";'
else if trim(strPageName)='Mail' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="Mail";'
else if trim(strPageName)='Address' then
SQL.Text:='SELECT * FROM AreaTable WHERE PageName="Address";'; Prepare;
Open;
First; while not eof do
begin
key:='root'; //根节点的 keyName是root for i:=1 to 5 do //从数据库的第1个字段到第5 字段依次处理
begin
ParentTxt:=key; //第一个字段为根节点节点,设置keyName为root //取字段值
NodeTxt:=Trim(FieldbyName('Area'+IntTostr(i)).asstring);
if NodeTxt=null then break; //如果内容为空此跳到下一记录 //节点的keyName值为第1节点+第二节点+第3节点...。如第1个字段'root'
//第二个为'root字段1' 第三个为'root字段1字段2'
key:=Trim(ParentTxt+NodeTxt);
//将ParentNode当成一个临时变量来用,查找有没有相同KeyName的节点
//如有则跳过
ParentNode:=FindParent(Treevw,key);
if ParentNode<>nil then
begin
continue; //有相同KeyName的节点则跳过这一字段
end; ParentNode:=FindParent(Treevw,ParentTxt); //查找父节点
New(aNode); //定义新的节点指针
aNode.RelatedInfo:=NodeTxt; //节点显示文本
aNode.keyName:=key; // 节点的关键值
aNode.ParentName:=ParentTxt; //父节点的关键值
aNode.lev:=i-1; // 节点的级别
if (ParentNode<>nil) and (i<>1) then
begin
CurNode:=Treevw.Items.AddChildObject(ParentNode,NodeTxt,aNode); end
else begin //如果没有父节点并且是第1条记录,则建立根节点 CurNode:=Treevw.Items.AddObjectFirst(ParentNode,NodeTxt,aNode);
end; CurNode.SelectedIndex:=1; end;{for} Next; end; {while}
close;
Free;
end;{with } Treevw.Items.EndUpdate;
result:=true;
end;//寻找父节点
function FindParent(TreeVw:TTreeview;idx:string):TTreeNode;
var
i:integer;
begin
result:=nil; for i:=0 to TreeVw.Items.Count-1 do
begin
if PCurNode(TreeVw.Items.Item[i].Data)^.keyName=idx then
begin
//showmessage( PCurNode(Treevw.Items.Item[i].Data)^.ParentName+' '+idx+'in findParent');
result:=TreeVw.Items.Item[i];
break;
end;
end;
end;
/////////////////////////////////
//第一个页,建立树时没有问题。建立完成后切换到别的页再切回时出问题。
procedure TfmCESMainForm.tsCESManagerShow(Sender: TObject);begin CreateTree(tvCES,'CES');
end; {procedure }
///////////////////////////////
//第二页,procedure TfmCESMainForm.tsMailShow(Sender: TObject);
begin
// CreateTree(tvMail,'Mail'); //加上此语句时出现问题。
end;//////////////////////////////
//主窗建立一个树时切换也不会有问题,但只是建两个就出现了问题。
procedure TfmCESMainForm.FormCreate(Sender: TObject);
//var
// strPageName:string;
begin
//try
//strPageName:='CES';
//CreateTree(tvCES,strPageName);
// strPageName:='Mail';
//CreateTree(tvMail,strPageName);
// except
// close;//CreateTree(tvAddress);
// end;
end;
/////////////////////////////
//下面都是我想释放内存的,但是都不行,解决不了问题。
procedure TfmCESMainForm.tvCESDeletion(Sender: TObject; Node: TTreeNode);
begin
//ClearTree(tvCES);
dispose(PCurNode(node.data));
end;procedure TfmCESMainForm.tvMailDeletion(Sender: TObject; Node: TTreeNode);
begin
//ClearTree(tvMail);
dispose(PCurNode(node.data));
end;procedure TfmCESMainForm.tsCESManagerHide(Sender: TObject);
begin
//ClearTree(tvCES);
end;procedure TfmCESMainForm.tsMailHide(Sender: TObject);
begin
// ClearTree(tvMail);
end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货