现有table和treeview控件
其中,table结构如下
myid:自动编号类型
菜单标题:string;
myparentid:integer;//指向myid,表明层次关系先定义记录类型
type
  PMyList = ^AList;
    AList = record
    MyParendID: string;
    xxx:integer; //为验证节点值特意增加的测试域
    MyNodeP: TTreeNode ;
  end; //定义生成节点的过程
procedure Tform1.MyNode(MyParentID:string;MyNodeT:TTreeNode);var
  ATempList: TList;
  I: Integer;
  ARecord:PMyList;
  s:string;
  node:TTreeNode;
begin
   ADOTable1.Filtered:=true;
   ADOTable1.Filter:=' MYParentID ='+MyParentID;
   if ADOTable1.RecordCount<1 then exit;
   ATempList := TList.Create;
   try
    ADOTable1.First;
    while not ADOTable1.Eof  do
    begin
       New(ARecord);
       s:='('+ADOTable1.fieldbyname('MyID').AsString +')'+ ADOTable1.fieldbyname('菜单标题').AsString  ;
       node:= TreeView1.Items.AddChild(MyNodeT   ,s) ;
       ARecord^.MyParendID:= ADOTable1.fieldbyname('myid').AsString;
       Arecord^.MyNodeP  :=node;
       Arecord^.xxx:=222;
       node.Data :=Arecord;  //将记录值赋给节点的data属性
       caption:=caption+inttostr(pmylist(node.data)^.xxx) ;
       ATempList.Add(Arecord);
       ADOTable1.Next;
      end;
     for I :=0 to ATempList.Count - 1 do
     begin
       Arecord:=ATempList.Items[i];
       MyNode(Arecord^.MyParendID,Arecord^.MyNodeP );
       end;
   finally
    for I := 0 to ATempList.Count - 1 do
      Dispose(ATempList[I]);
    ATempList.Free;
    ADOTable1.Filtered:=false;
  end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  MyNode('0',nil  );
end;//检查节点的data属性
procedure TForm1.Button1Click(Sender: TObject);
var
  CurItem: TTreeNode;
begin
listbox1.Clear;
  CurItem := TreeView1.Items.GetFirstNode;
  while CurItem<>nil do
  begin
   showmessage(curitem.Text); //运行结果正常
   showmessage(pmylist(curitem.Data )^.MyParendID ); //报AV错,取不到值
   showmessage(inttostr(pmylist(curitem.Data )^.xxx)); //取到了值,有部分是生成节点时的222,另外一部分不是.
   CurItem := CurItem.GetNext;
  end;
end;
现请高手指点,Button1Click中那两句取节点data属性的执行结果为什么不正确?

解决方案 »

  1.   

    type
      PMyList = ^AList;
        AList = record
        MyParendID: string;
        xxx:integer; //为验证节点值特意增加的测试域
        MyNodeP: TTreeNode ;
      end;可能是这个类型定义的问题,MyParendID定义最好用Array of char或者指定String长度,例如:MyParentID: String[10];不指定MyParentID的String长度,在new(aPMyList)时,编译器不知道申请多大的内存块块!
      

  2.   

    ============================================================
    加上packed试试!
    ============================================================type
      PMyList = ^AList;
      AList = packed record
        MyParendID: string;
        xxx:integer; //为验证节点值特意增加的测试域
        MyNodeP: TTreeNode ;
      end;
      

  3.   

    这个语句放在销毁treeview时才执行。
    for I := 0 to ATempList.Count - 1 do
      Dispose(ATempList[I]);
      

  4.   

    建议搂主研究一下OnCreateNodeClass事件,并注意var NodeClass: TTreeNodeClass参数。你可以从TTreeNode中重载一个类,在这个事件中将你的类赋值给NodeClass,访问节点时,强制转换你自己的类即可。
    如果有问题,可以继续提问。
      

  5.   

    参考
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, StdCtrls;type
      PMyList = ^AList;
      AList = packed record
        MyParendID: string;
        xxx:integer; //为验证节点值特意增加的测试域
      end;
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); var
      MyList : PMyList;
      t : TtreeNode;
    begin
      new(mylist);
      MyList.MyParendID:='sdf';
      MyList.xxx:=1;
      TreeView1.Items.AddChildObject(nil,mylist.MyParendID,Tobject(MyList));
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      index : integer;
    begin  Showmessage(PMyList(TreeView1.Items[0].Data)^.MyParendID)
    end;end.
      

  6.   

    估计节点没有加进去
    showmessage(pmylist(curitem.Data )^.MyParendID ); //报AV错,取不到值