我用findfirst和findnext遍历了要显示的目录,想用递归算法来把文件名和文件夹名显示在treeview的控件里,写来写去都有问题,有高手写过类似的算法吗,提供好的算发吗?最好用代码形式!谢谢

解决方案 »

  1.   

    我程序里的一段
    procedure TForm5.LoadTreeView;
    var
      strsql:string;
    begin
      try//    DataModule3.ADOTable3.open;
    //    DataModule3.ADOTable3.Locate('DTname',RzComboBox1.Text,[lopartialkey]);
    //    tid:=inttostr(DataModule3.ADOTable3.FieldByName('id').value);
        strsql:='select * from T where NodeType="bs"';
        DQ.Active :=false;
        DQ.SQL.Clear ;
        DQ.SQL.Add(strsql);
        DQ.Active :=true;
        DQ.Filtered :=true;
        DQ.Filter := 'Parent=0';
        U_DiGui(0,RzTreeView1.TopItem );//从当前0层开始递归建树
      except
        showmessage('字典里没有数据!');
      end;
    end;
    procedure TForm5.U_DiGui(parentID:Cardinal;ParentNode:TTreeNode);
    var
      tmpTBData:array of TableData;
      i,j:integer;
      tmpNode:TTreeNode;begin
      j:=DQ.RecordCount;
      setlength(tmpTBData,j);//保存递规上一层结点值
      for i:=0 to j-1 do begin
        tmpTBData[i].ID := Cardinal(DQ.fieldbyname('ID').value);
        tmpTBData[i].Name  := DQ.fieldbyname('Name').value;
        tmpTBData[i].ParentID  := Cardinal(DQ.fieldbyname('Parent').value);
        DQ.Next;
      end;
      for i:=0 to j-1 do begin //递规调用建立所有结点
        tmpNode:=RzTreeView1.Items.AddChild(ParentNode,tmpTBData[i].Name);
     //   tmpNode.ImageIndex:=2;
        new(pData);
        pData^.ID:=tmpTBData[i].ID;
        tmpNode.Data:=pData;
        DQ.Filter := 'Parent=' + IntToStr(Integer(tmpTBData[i].ID));
        if DQ.RecordCount >0 then begin
          U_DiGui(tmpTBData[i].ID,tmpNode );
        end;
      end;
    end;
      

  2.   

    用Delphi实现Windows文件夹管理树............................ 李鹏 薛志东(2.29)
    以下:unit BrowseTreeView;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ShlObj,ComCtrls;type
      PTreeViewItem=^TTreeViewItem;
      TTreeViewItem=record
       ParentFolder:IShellFolder;
       //节点对应的文件夹的父文件夹的IShellFolder接口
       Pidl,FullPidl:PItemIDList;
       //节点对应的文件夹的相对和绝对项目标识符列表
       HasExpanded:Boolean;//节点是否展开
      end;
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure TreeView1Expanding(Sender: TObject; Node: TTreeNode;
          var AllowExpansion: Boolean);  private
        { Private declarations }
        FItemList:TList;
        procedure SetTreeViewImageList;
        procedure FillTreeView(Folder:IShellFolder;FullPIDL:PItemIDList;ParentNode:TTreeNode);  public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}
    uses
      ActiveX,ComObj,ShellAPI,CommCtrl;
      //以下是几个对项目标识符进行操作的函数procedure DisposePIDL(ID:PItemIDList);
    var
      Malloc:IMalloc;
    begin
      if ID= nil then Exit;
      OLECheck(SHGetMalloc(Malloc));
      Malloc.Free(ID);
    end;function CopyItemID(ID:PItemIDList):PItemIDList;
    var
      Malloc:IMalloc;
    begin
      Result:=nil;
      OLECheck(SHGetMalloc(Malloc));
      if Assigned(ID) then
      begin
        Result:=Malloc.Alloc(ID^.mkid.cb+sizeof(ID^.mkid.cb));
        CopyMemory(Result,ID,ID^.mkid.cb+sizeof(ID^.mkid.cb));
      end;
    end;function NextPIDL(ID:PItemIDList):PItemIDList;
    begin
      result:=id;
      Inc(PChar(result),id^.mkid.cb);
    end;function GetPIDLSize(ID:PItemIDList):Integer;
    begin
      result:=0;
      if  Assigned(ID) then
      begin
        result:=sizeof(ID^.mkid.cb);
        while ID^.mkid.cb <> 0 do
        begin
          Inc(result,ID^.mkid.cb);
          ID:=NextPIDL(ID);
        end;
      end;
    end;function CreatePIDL(Size:Integer):PItemIDList;
    var
      Malloc:IMalloc;
      HR:HResult;
    begin
      result:=nil;
      HR:=SHGetMalloc(Malloc);
      if Failed(HR) then Exit;
      try
        Result:=Malloc.Alloc(Size);
        if Assigned(Result) then
          FillChar(Result^,Size,0);
      finally
      end;
    end;function ConcatPIDLs(ID1,ID2:PItemIDList):PItemIDList;
    var
      cb1,cb2:Integer;
    begin
      if Assigned(ID1) then
        cb1:=GetPIDLSize(ID1)-sizeof(ID1^.mkid.cb )
      else
        cb1:=0;
        cb2:=GetPIDLSize(ID2);
        result:=CreatePIDL(cb1+cb2);
        if Assigned(Result) then
        begin
          if Assigned(ID1) then
            CopyMemory(Result,ID1,cb1);
            CopyMemory(PChar(Result)+cb1,ID2,cb2);
        end;
    end;
    //将二进制表示的项目标识符列表转换成有可识的项目名function GetDisplayName(Folder:IShellFolder;PIDL:PItemIDList;ForParsing:Boolean):String;
    var
      StrRet:TStrRet;
      P:PChar;
      Flags:Integer;
    begin
      result:='';
      if ForParsing then
        Flags:=SHGDN_FORPARSING
      else
        Flags:=SHGDN_NORMAL;
        Folder.GetDisplayNameOf(pidl,flags,StrRet);
        case StrRet.uType of
          STRRET_CSTR:
            SetString(Result,StrRet.cStr,StrLen(StrRet.cStr));
          STRRET_OFFSET:
          begin
            P:[email protected][StrRet.uOffset-sizeof(PIDL.mkid.cb)];
            SetString(Result,P,PIDL.mkid.cb-StrRet.UOffset);
          end;
        end;
    end;function GetIcon(PIDL:PItemIDList;Open:Boolean):Integer;
    const
      IconFlag=SHGFI_PIDL or SHGFI_SYSICONINDEX or SHGFI_SMALLICON;
    var
      FileInfo:TSHFileInfo;
      Flags:Integer;
    begin
      if Open then
        Flags:=IconFlag or SHGFI_OPENICON
      else
        Flags:=IconFlag;
        SHGetFileInfo(PChar(PIDL),0,FileInfo,sizeof(TSHFileInfo),Flags);
        result:=FileInfo.iIcon;
    end;
    //获得每个文件夹在系统中的图标
        
    procedure GetItemIcons(FullPIDL:PItemIDList;TreeNode:TTreeNode);
    begin
      with TreeNode do
      begin
        ImageIndex:=GetIcon(FullPIDL,False);
        SelectedIndex:=GetIcon(FullPIDL,True);
      end;
    end;
    //获得系统的图标列表procedure TForm1.SetTreeViewImageList;
    var
      imagelist:thandle;
      fileinfo:tshfileinfo;
    begin
      imagelist:=shgetfileinfo(Pchar('c:\'),0,fileinfo,sizeof(tshfileinfo),shgfi_sysiconindex or shgfi_smallicon);
      if imagelist<>0 then
        treeview_setimagelist(treeview1.handle,imagelist,0);
    end;
    //生成文件夹管理树procedure TForm1.FillTreeView(Folder:IShellFolder;FullPIDL:PItemIDList;ParentNode:TTreeNode);
    var
      TreeViewItem:PTreeViewItem;
      EnumIDList:IEnumIDList;
      PIDLs,FullItemPIDL:PItemIDList;
      NumID:LongWord;
      ChildNode:TTreeNode;
      Attr:Cardinal;
    begin
      try
        OLECheck(Folder.EnumObjects(Handle,SHCONTF_FOLDERS,EnumIDList));
        while EnumIDList.Next(1,PIDls,NumID)=S_OK do
        begin
          FullItemPIDL:=ConcatPIDLs(FullPIDL,PIDLs);
          TreeViewItem:=New(PTreeViewItem);
          TreeViewItem.ParentFolder:=Folder;
          TreeViewItem.Pidl:=CopyItemID(PIDLs);
          TreeViewItem.FullPidl:=FullItemPIDL;
          TreeViewItem.HasExpanded:=False;
          FItemList.Add(TreeViewItem);
          ChildNode:=TreeView1.Items.AddChildObject(ParentNode,GetDisplayName(Folder,PIDLs,False),TreeViewItem);
          GetItemIcons(FullItemPIDL,ChildNode);
          Attr:=SFGAO_HASSUBFOLDER or SFGAO_FOLDER;
          Folder.GetAttributesOf (1,PIDLs,Attr);
          if Bool(Attr and(SFGAO_HASSUBFOLDER or SFGAO_FOLDER)) then
            if Bool(Attr and SFGAO_FOLDER) then
              if Bool(Attr and SFGAO_HASSUBFOLDER) then
                ChildNode.HasChildren:=True;
        end;
      except
      // 你可在此处对异常进行处理
      end;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    var
      I:Integer;
    begin
      try
        for I:=0 to FItemList.Count-1 do
        begin
          DisposePIDL(PTreeViewItem(FItemList[i]).PIDL);
          DisposePIDL(PTreeViewItem(FItemList[i]).FullPIDL);
        end;
      FItemList.Clear;
      FItemList.Free;
      except
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      Folder:IshellFolder;
    begin
      SetTreeViewImageList;
      OLECheck(ShGetDesktopFolder(Folder));
      FItemList:=Tlist.Create;
      FillTreeView(folder,nil,nil);end;procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    var
      tVItem:PTreeViewItem;
      SHFolder:IShellFolder;
    begin
      TVItem:=PTreeViewItem(Node.Data);
      if TVItem.HasExpanded then Exit;
        OLECheck(TVItem.ParentFolder.BindToObject(TVItem^.Pidl,Nil,IID_IShellFolder,Pointer(SHFolder)));
        FillTreeView(SHFolder,TVItem^.FullPidl,Node);
        Node.AlphaSort;
        TVItem^.HasExpanded:=True;end;end.-------------------------------------
      

  3.   

    或者用这个:procedure DirToTreeView(Tree: TTreeView; Directory: string; Root: TTreeNode; IncludeFiles:
      Boolean);
    var
      SearchRec         : TSearchRec;
      ItemTemp          : TTreeNode;
    begin
      with Tree.Items do
      try
        BeginUpdate;
        if Directory[Length(Directory)] <> '\' then Directory := Directory + '\';
        if FindFirst(Directory + '*.*', faDirectory, SearchRec) = 0 then
        begin
          repeat
            if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
            begin
              if (SearchRec.Attr and faDirectory > 0) then
                Root := AddChild(Root, SearchRec.Name);
              ItemTemp := Root.Parent;
              DirToTreeView(Tree, Directory + SearchRec.Name, Root, IncludeFiles);
              Root := ItemTemp;
            end
            else if IncludeFiles then
              if SearchRec.Name[1] <> '.' then
                AddChild(Root, SearchRec.Name);
          until FindNext(SearchRec) <> 0;
          FindClose(SearchRec);
        end;
      finally
        EndUpdate;
      end;
    end;-----------------------------------------------------------------
    我是中国鹰派!
    拒绝日货!打倒小日本!
      

  4.   

    可以用Shell,Delphi自己带一个例子
      

  5.   

    delphi6自带这个控件!
    tshelltreeview