谁能帮我解释下这段Treeview的代码,特别是我打问号的几句,定给高分 
树的结构和表中的字段如下:
公司机构【总人数】
- 一级部门department.dep
  - 二级部门department.sdep
     - 员工employee.name
department表和employee表是靠dep_id字段关联的,
employee表与experience、train、behave表都是靠num字段关联的。
相关代码如下:
private
    { Private declarations }
    FNum: string;
    Fdep_id: string;
    procedure RefreshTreeView;
public
    { Public declarations }
  end;
  PIndexRecord = ^TIndexRecord;  
  TIndexRecord = packed record   
    num: string;
    Dep_id: string;
    Code: TTreeNode;  ??
    Next: PIndexRecord;  ??
  end;
var
  EmpForm: TEmpForm;
  Temp: PIndexRecord;  ??
  Flag: Boolean;   ??implementationuses UnitDM;{$R *.dfm}var
  FirstPointer, LastPointer, First, Last: PIndexRecord;
  aqEmployee,ADQ2, ADQ3,ADQ4: TADOQuery;
procedure TEmpForm.RefreshTreeView;
var
  Node0: TTreeNode;
  Node1, Node2: array of TTreeNode;
  i,Index1, Index2: Integer;
  Temp, Temp1: PIndexRecord;
begin
  dm.OpenInfo; 
  TreeView1.Items.Clear;
  ADQ1:= TADOQUery.Create(nil);
  ADQ2:= TADOQuery.Create(nil);
  ADQ3:= TADOQuery.Create(nil);
  ADQ4:= TADOQuery.Create(nil);
  aqEmployee:=TADOQuery.Create(nil);
  Index1:= 0;
  ADQ1.Connection:= DM.ADOConnection1;
  ADQ2.Connection:= DM.ADOConnection1;
  ADQ3.Connection:= DM.ADOConnection1;
  ADQ4.Connection:= DM.ADOConnection1;
  aqEmployee.Connection:=DM.ADOConnection1;  FillData;  aqEmployee.Close;
  aqEmployee.SQL.Clear;
  aqEmployee.SQL.Add('select * from employee');
  aqEmployee.Open;
  DM.aqEmp.Close;
  DM.aqEmp.SQL.Clear;
  DM.aqEmp.SQL.Add('select * from employee');
  DM.aqEmp.Open;  Temp:= New(PIndexRecord);
  Temp1:= New(PIndexRecord);  FirstPointer:= Temp;
  First:= Temp1;  ADQ1.Close;
  ADQ1.SQL.Clear;
  ADQ1.SQL.text:='Select dep_id,dep From department where dep_id in ' + #13#10 +
               '(select Min(dep_id) from department group by dep) ' + #13#10 +
                'order by dep_id asc';
  ADQ1.Open;  if not ADQ1.Eof then
  begin
    TreeView1.AutoExpand := true;
    TreeView1.ReadOnly := true;
    Node0 := TreeView1.Items.AddFirst(nil, '公司机构[' + IntToStr(aqEmployee.RecordCount) + '人]');
  end
  else
    Exit;  SetLength(Node1, ADQ1.RecordCount);  while not ADQ1.Eof do
    begin
      with dm.aqEmp do
      begin
        Filtered := false;
        Filter := 'dep = ' + QuotedStr(adq1.FieldValues['dep']); 
        Filtered := true;
      end;
      Node1[Index1]:= TreeView1.Items.AddChild(Node0, ADQ1.FieldByName('dep').AsString+'[' + IntToStr(dm.aqEmp.RecordCount) + ']');
      Node1[Index1].ImageIndex:= 0;      ADQ2.Close;
      ADQ2.SQL.Clear;
      ADQ2.SQL.Add('SELECT * FROM department WHERE dep = ''' + ADQ1.FieldByName('dep').AsString + '''');
      ADQ2.Open;      Index2:= 0;
      if not ADQ2.IsEmpty then
        begin
          SetLength(Node2, ADQ2.RecordCount);          while not ADQ2.Eof do
            begin
              Node2[Index2]:= TreeView1.Items.AddChild(Node1[Index1], ADQ2.FieldByName('sdep').AsString);
              Node2[Index2].ImageIndex:= 0;              Temp1.num:= '';   ??
              Temp1.Dep_id:= ADQ2.FieldByName('dep_id').AsString;  ? 
              Temp1.Code:= Node2[Index2]; ??  
             
              ADQ3.Close;
              ADQ3.SQL.Clear;
              ADQ3.SQL.Add('SELECT * FROM employee WHERE dep_id = ''' + ADQ2.FieldByName('dep_id').AsString + '''');
              ADQ3.Open;              if not ADQ3.IsEmpty then
                while not ADQ3.Eof do
                  begin
                    Temp.num:= ADQ3.FieldByName('num').AsString;
                    Temp.Dep_id:= ADQ3.FieldByname('dep_id').AsString;
                    Temp.Code:=
                      TreeView1.Items.AddChildObject(Node2[Index2], ADQ3.FieldByName('name').AsString,temp);
                    Temp.Code.ImageIndex:= 2;
                    ADQ3.Next;
                    Temp.Next:= New(PIndexRecord);
                    Temp:= Temp.Next;
                  end;              Inc(Index2);
              ADQ2.Next;
              Temp1.Next:= New(PIndexRecord);
              Temp1:= Temp1.Next;
            end;
        end;      Inc(Index1);
      ADQ1.Next;    end;
  ADQ1.Close;
  ADQ2.Close;
  ADQ3.Close;
  LastPointer:= Temp;
  Last:= Temp1;
  TreeView1.Refresh;  DataSource1.DataSet:= ADQ1;
  DataSource2.DataSet:= ADQ2;
  DataSource3.DataSet:= ADQ3;
  DataSource4.DataSet:= ADQ4;  for i := 0 to TreeView1.Items.Count - 1 do
  if TreeView1.Items[i].Data <> nil then
  begin
    TreeView1.Selected := TreeView1.Items[i];
    Exit;
  end;
end;procedure TEmpForm.TreeView1Click(Sender: TObject);
var
  Temp, Temp1: PIndexRecord;
  Flag: Boolean;   ??干吗用的
begin
  Temp:= FirstPointer;
  Temp1:= First;
  Flag:= False;   while Temp <> nil do
    begin
      if Temp.Code = TreeView1.Selected then
        begin
          Flag:= True;  ??
          Break;
        end;      Temp:= Temp.Next;
      if Temp = LastPointer then
        Break;
    end;  if Flag then   
    begin
      ADQ1.Close;
      ADQ1.SQL.Clear;
      ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp.num + '''');
      ADQ1.Open;
      LoadImage(ADQ1.FieldByName('Photo'));      ADQ2.Close;
      ADQ2.SQL.Clear;
      ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp.num + '''');
      ADQ2.Open;      ADQ3.Close;
      ADQ3.SQL.Clear;
      ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp.num + '''');
      ADQ3.Open;      ADQ4.Close;
      ADQ4.SQL.Clear;
      ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp.num + '''');
      ADQ4.Open;      FNum:= Temp.num;   ??
      Fdep_id:= Temp.Dep_id;   ??
    end
  else
    begin
      while Temp1 <> Last do
        begin
          if Temp1.Code = TreeView1.Selected then
            begin
              Flag:= True;
              Break;
            end;          Temp1:= Temp1.Next;
        end;      if Flag then  ??为什么要判断两次
        begin
          ADQ1.Close;
          ADQ1.SQL.Clear;
          ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp1.num + '''');
          ADQ1.Open;          ADQ2.Close;
          ADQ2.SQL.Clear;
          ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp1.num + '''');
          ADQ2.Open;          ADQ3.Close;
          ADQ3.SQL.Clear;
          ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp1.num + '''');
          ADQ3.Open;          ADQ4.Close;
          ADQ4.SQL.Clear;
          ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp1.num + '''');
          ADQ4.Open;          FNum:= Temp1.num;
          Fdep_id:= Temp1.Dep_id;
        end;
    end;end;

解决方案 »

  1.   

    TIndexRecord = packed record   //这里是定义一个记录类型数据
        num: string;
        Dep_id: string; 
        Code: TTreeNode;  ?? //对应的节点
        Next: PIndexRecord;  ??//指向下一个节点
      end;Temp1.num:= '';   ??这里就是上面定义的记录
    Temp1.Dep_id:= ADQ2.FieldByName('dep_id').AsString;  ? 
    Temp1.Code:= Node2[Index2]; ??    Flag: Boolean;   ??干吗用的  用于标识是否是要第一个节点算了,你还是好好去看一下记录类型和指针这些知识吧
      

  2.   

    flag应该是用来判断当前节点是否有子节点的吧
      

  3.   

    这段代码是把TreeView中部门结点、员工结点及它们的编号信息保存在两个自定义的链表FirstPointer、First中。链表结点的定义:PIndexRecord = ^TIndexRecord;  //链表结点指针类型
    TIndexRecord = packed record   //链表结点记录类型
        num: string;        //元素1  员工编号?
        Dep_id: string;     //元素2  部门编号
        Code: TTreeNode;    //元素3  对应的Treeview结点,TreeView结点的类型为TTreeNode
        Next: PIndexRecord; //元素4  链表的下一个结点
      end;这样做的目的就是为了当选中某个Treeview结点时,从链表FirstPointer,First中找对应结点的员工编号,并显示相关的信息。Flag表示是否在链表中找到相应TreeNode,找到为true。由于有两个链表,当然查找两次了。其实不用这样做,把树结点的信息,比如Num,dep_id等信息绑定到树结点的Data。点击的时候直接从Data取信息就可以了。比如:
      

  4.   

    unit Unit1;interfaceuses
       Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
       Dialogs, ComCtrls;type
       TNodeType = (ntUnknow, ntDepartment, ntSDepartment, ntEmployee);
       PNodeAttr = ^TNodeAttr;
       TNodeAttr = record
          NodeType: TNodeType;
          ID: string;
       end;
       TForm1 = class(TForm)
          TreeView1: TTreeView;
          procedure FormCreate(Sender: TObject);
          procedure TreeView1Click(Sender: TObject);
       private
        { Private declarations }
          function NodeAttr(Node: TTreeNode): TNodeType;
       public
        { Public declarations }
       end;var
       Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
       function AddNode(AType: TNodeType; AParent: TTreeNode;
          const AID, AText: string): TTreeNode;
       var
          PAttr: PNodeAttr;
       begin
          New(PAttr);
          PAttr^.NodeType := AType;
          PAttr^.ID := AID;
          Result := TreeView1.Items.AddChild(AParent, AText);
          Result.Data := PAttr;
       end;
    var
       Node: TTreeNode;
    begin
       Node := AddNode(ntDepartment, nil, '1', '部门');
       Node := AddNode(ntSDepartment, Node, '10', '部门二');
       AddNode(ntEmployee, Node, '123456', '员工一');
    end;function TForm1.NodeAttr(Node: TTreeNode): TNodeType;
    begin
       if Assigned(Node) then
          Result := PNodeAttr(Node.Data)^.NodeType
       else
          Result := ntUnknow;
    end;procedure TForm1.TreeView1Click(Sender: TObject);
    begin
       with TreeView1 do
       begin
          if NodeAttr(Selected) = ntEmployee then
             ShowMessage('ID:' + PNodeAttr(Selected.Data)^.ID);
       end;
    end;end.
      

  5.   

    谢谢各位了,特别感谢HsWong(),写的很详细