unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, DB, ADODB; type PNodeInfoEx = ^TNodeInfoEx; TNodeInfoEx = Packed Record NodeID : Integer; ParentID : Integer; NodeType : Integer; ChnNodeTitle : String; ImageIndex: SmallInt; SelectedIndex: SmallInt; end; TForm1 = class(TForm) tv1: TTreeView; btn1: TButton; qry1: TADOQuery; procedure btn1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } function StaticBuildTree(TreeView:TTreeView ):Boolean; function AddTreeItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode; function FindTreeItem(TreeView:TTreeView; CurNodeID:integer): TTreeNode; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function TForm1.StaticBuildTree(TreeView:TTreeView ):Boolean; var AddNodeInfo: PNodeInfoEx; the begin the Result: = False; qry1.LoadFromFile ( ' c: /AdminixTree.xml ' ); // here to XML file as a data source Treeview.Items.BeginUpdate; // Remember: Before adding bulk data to use BeginUpdate, to temporarily close certain events triggered by the addition of data (such as OnChange events, etc.) Treeview.Items.Clear; // Clear Treeview the try the try IF qry1.RecordCount> 0 the then the begin qry1.First; the while Not qry1 .EOF do the begin New (AddNodeInfo); // generating structure AddNodeInfo ^ .NodeID: = qry1.FieldByName ('NODE_ID').AsInteger; AddNodeInfo^.ParentID := qry1.FieldByName('PARENT_ID').AsInteger; AddNodeInfo^.NodeType := qry1.FieldByName('NodeType').AsInteger; AddNodeInfo^.ChnNodeTitle := qry1.FieldByName('ChnNodeTitle').AsString; AddNodeInfo^.ImageIndex := qry1.FieldByName('ImageIndex').AsInteger; AddNodeInfo^.SelectedIndex := qry1.FieldByName('SelectedIndex') .AsInteger; AddTreeItem (Treeview, AddNodeInfo); // pointer to structure stored in Treeview qry1.Next; End ; End ; the except Application.MessageBox ( ' spanning tree node failure ' , MB_ICONSTOP + MB_OK); The raise ; / / abnormality superior throwing End ; qry1.Close; the Result: = True; the finally Treeview.Items.EndUpdate; End ; End ; // when joining node, should be added is determined parent node or a child node, it is determined ParentID is based on the presence or absence of the node in the tree nodes existing in function TForm1.AddTreeItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode; var ParentNode: TTreeNode; begin ParentNode := FindTreeItem(Treeview,AddNodeInfo^.ParentID); If ParentNode <> nil then Result := Treeview.Items.AddChildObject(ParentNode, Trim(AddNodeInfo.ChnNodeTitle), Pointer(AddNodeInfo)) else Result := Treeview.Items.AddObject(ParentNode, Trim(AddNodeInfo.ChnNodeTitle), Pointer(AddNodeInfo)); if Result<>nil then begin Result.ImageIndex := AddNodeInfo.ImageIndex; Result.SelectedIndex: = AddNodeInfo.SelectedIndex; End ; End ; // this is determined whether there is a parent node function TForm1.FindTreeItem (the TreeView: TTreeView; CURNODEID: Integer): TTreeNode; var I: Integer; the begin the Result: = nil ; for I: = 0 to Treeview.Items.Count- . 1 do the begin IF CURNODEID = PNodeInfoEx (Treeview.Items [I] .Data) ^ NodeID. the then the begin the Result: = Treeview.Items [I]; the Exit; End ; End ; End ; // tree structure Procedure TForm1.btn1Click (Sender: TObject); the begin StaticBuildTree (TV1) End ; // when the form releasing structure pointers to nodes in the tree must take to relieve, for the Why should Dispose casts after release, before a special explanation, this is not tired Procedure TForm1.FormDestroy (Sender: TObject); var I: Integer; the begin for I: = 0 to tv1.Items.Count- . 1 do the begin the Dispose (PNodeInfoEx (tv1.Items [i] .Data)) End ; End ; End . // how to access the tree node? procedure TForm1.tv1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var pNode:TTreeNode; begin pNode:=tv1.GetNodeAt(x,y); if (pNode<>nil) and (Button=mbleft) then ShowMessage(PNodeInfoEx(pNode.Data)^.ChnNodeTitle); end;