首页  编辑  

得到“桌面”及其下的子目录

Tags: /超级猛料/Stream.File.流、文件和目录/目录/   Date Created:

《电脑编程技巧与维护》2000年第二期中的一篇文章,希望对你有帮助。

用Delphi实现Windows文件夹管理树............................ 李鹏 薛志东(2.29)

以下:

unit BrowseTreeView;

interface

uses

 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:=@PIDL.mkid.abID[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.