我在写一个管理方面的东东,要用到在一个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.