我程序里的一段 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;
用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.-------------------------------------
或者用这个: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;----------------------------------------------------------------- 我是中国鹰派! 拒绝日货!打倒小日本!
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;
以下: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.-------------------------------------
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;-----------------------------------------------------------------
我是中国鹰派!
拒绝日货!打倒小日本!
tshelltreeview