别忘了加分噢!!!<br>Delphi 编写Windows 资源管理器<br><br>编写资源管理器,Delphi 有最简单的方法,就是在form上加上一个<br>TShellComboBox1控件,一个TShellTreeView1控件和一个TShellListView1控件。然后分别指定他们的属性值为对应的属性就可以了。<br>但是这不是一个程序员所要的。因为你不能对上述的这些内容进行操作,所以,我<br>在这里要说的是第二种,也就是最为激动人心的有自己写的代码来实现以上的功能。<br>用程序实现的好处是控制随心所欲。这把这种方法用到了我写的木马当中。<br>在服务器端有我的一个服务程序,在我的机子上有我的另一个客户端程序。<br>当我要用我的客户端连接服务器端的时候,比如202.206.242.119,服务器端就把<br>本机(202.206.242.119)上的所有磁盘信息发送给我。(比如有c:,d:,e:,f:....)<br>当我在本地(我的机子)上点击"c:"时候,服务器端就把202.206.242.119上的<br>c:盘上的所有文件和目录发送给我,我一目了然。我还可以在他的机子上新建、删除<br>运行等各种文件。好不好玩啊?~_~当然,他首先得运行我的木马程序。<br>国内赫赫有名的"冰河"我想大家都用过吧,不错吧。就像是管理自己机子的资料管理器,好了,不再废话了,让我们开始这激动人心的一刻吧!<br><br><br>首先要明白程序的流程,不然我不是在这瞎说一桶吗?<br><br>第一步就是找到机子上的所有的硬盘,第二就是找到机子上对应硬盘下的所有文件和图标。<br>找硬盘的方法很多,我用的是Winapi函数:getdrivetype,因为它比较简单。<br>打文件就是findfirst和findnext就可以了。<br>剩下的就是怎样向ttreeview中填充了。 <br>好了,开始吧!<br><br>新建一个工程,然后窗体的caption为"资源管理器"<br>在窗体上添加一个TTreeview控件命名为dir,一个tlistview控件命名为wfile,两个tpopupmenu控件<br>两个timagelist控件.dir 对应第一个tpopupmemu,wfile对应第二个tpopupmemu。<br>第一个tpopupmemu的Items分别为:删除,新建文件夹,重命名。<br>第二个tpopupmemu的Items分别为:查看,删除,新建文件,新建文件夹,重命名。其中,查看的子项为:<br>大图标,小图标,列表和详细资料。<br><br>unit Unit1;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, ExtCtrls, ComCtrls, ImgList,shellapi, StdCtrls, Buttons, Menus,<br> Grids, DBGrids;<br><br>type<br> Tlistfile = class(TForm)<br> dir: TTreeView;<br> Wfile: TListView;<br> Splitter1: TSplitter;<br> ImageList1: TImageList;<br> PopupMenu1: TPopupMenu;<br> N1: TMenuItem;<br> Image1: TImage;<br> ImageList2: TImageList;<br> N2: TMenuItem;<br> R1: TMenuItem;<br> PopupMenu2: TPopupMenu;<br> D1: TMenuItem;<br> N3: TMenuItem;<br> R2: TMenuItem;<br> M1: TMenuItem;<br> zt: TStatusBar;<br> V1: TMenuItem;<br> N4: TMenuItem;<br> N5: TMenuItem;<br> N6: TMenuItem;<br> M2: TMenuItem;<br> L1: TMenuItem;<br> N7: TMenuItem;<br> procedure FormCreate(Sender: TObject);<br> procedure dirCollapsed(Sender: TObject; Node: TTreeNode);<br> procedure dirExpanded(Sender: TObject; Node: TTreeNode);<br> procedure WfileDblClick(Sender: TObject);<br> procedure dirClick(Sender: TObject);<br> procedure N1Click(Sender: TObject);<br> procedure dirEdited(Sender: TObject; Node: TTreeNode; var S: String);<br> procedure WfileEdited(Sender: TObject; Item: TListItem; var S: String);<br> procedure dirKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);<br> procedure D1Click(Sender: TObject);<br> procedure R2Click(Sender: TObject);<br> procedure N3Click(Sender: TObject);<br> procedure M1Click(Sender: TObject);<br> procedure N2Click(Sender: TObject);<br> procedure N4Click(Sender: TObject);<br> procedure L1Click(Sender: TObject);<br> procedure M2Click(Sender: TObject);<br> procedure N7Click(Sender: TObject);<br> private<br> procedure filedir(dirname:string;node:ttreenode);//查找文件<br> procedure wmdropfiles(var msg:twmdropfiles);message wm_dropfiles;<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> listfile: Tlistfile;<br> fileinfo:shfileinfo;<br> f:array [0..0,0..2] of string;<br> ListItem: TListItem;<br> filename,names:string;<br> pathname:string;<br> node1,node3:ttreenode;<br>implementation<br><br>{$R *.dfm}<br><br>//以上是窗体上的控件和属性.<br><br>function IsValidDir(SearchRec:TSearchRec):Boolean;<br>begin<br> if ((SearchRec.Attr=16)or (searchrec.Attr =17)or<br> (searchrec.Attr =18)or (searchrec.Attr =22)<br> or (searchrec.Attr =49)or (searchrec.Attr =48))<br> and (SearchRec.Name<>'.')<br> and (SearchRec.Name<>'..') then<br> Result:=True<br> else<br> Result:=False;<br> //showmessage(inttostr(searchrec.Attr ));<br>end;<br>////////以上是一个函数,功能是判断一个文件是不是文件夹。<br><br>function panel(node:ttreenode):string;<br>var str:string;<br>node2:ttreenode;<br>begin<br> try<br> node2:=node.Parent;//返回父节点<br> str:=node2.Text+str;<br> node1:=node2;<br><br> filename:=str+'/'+filename;<br> panel(node2);<br> except<br> panel:=filename;<br> end;<br>end;<br>///////一个递归函数,找到node的父节点。<br><br>procedure tlistfile.wmdropfiles(var msg:twmdropfiles);<br>var numfiles:longint;<br> i:longint;<br> buffer:array[0..255] of char;<br>begin<br> showmessage('asdfasdf');<br>end;<br>////////用兴趣的朋友可以在这处理鼠标拖放,本人没有处理,只是打到了。<br><br>procedure tlistfile.filedir(dirname:string;node:ttreenode);<br>var searchrec:tsearchrec;<br> filename:string;<br> node1:ttreenode;<br> i:integer;<br>begin<br> try<br> for i:=node.Count -1 downto 0 do<br> begin<br> node.Item .Delete ;<br> end;<br> except<br> end;<br> filename:=dirname+'/*.*';<br> wfile.Clear;<br> listfile.ImageList2.Clear;<br> listitem:=wfile.Items.Add;<br> listitem.Caption:='..';<br> if findfirst(filename,faAnyFile,searchrec)=0 then<br> begin<br> while findnext(searchrec)=0 do<br> begin<br> if IsValidDir(searchrec) then<br> begin<br> node1:=listfile.dir.Items.AddChild(node,searchrec.Name );<br> node1.ImageIndex:=1;<br> node1.SelectedIndex:=2;<br> listfile.dir.Items.AddChild(node1,'' );<br><br> shgetfileinfo(pchar(dirname+'/'+searchrec.Name ),0,fileinfo,sizeof(fileinfo),shgfi_icon);<br> listfile.image1.Picture.Icon.Handle:=fileinfo.hIcon;//返回文件的图标<br> listfile.ImageList2.AddIcon(listfile.image1.Picture.Icon);//添加图标<br><br> f[0,0]:=searchrec.Name;//+' '+inttostr(searchrec.Attr );<br> f[0,1]:=inttostr(searchrec.Size);<br> f[0,2]:=datetimetostr(filedatetodatetime(searchrec.Time ));<br><br> listitem:=wfile.Items.Insert(1);<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add('');<br> listitem.SubItems.add(f[0,2]);<br> wfile.Items[1].ImageIndex:=imagelist2.Count-1 ;<br> wfile.Items[0].ImageIndex:=imagelist2.Count-1;<br> end<br> else<br> begin<br> if searchrec.Name <>'..' then<br> begin<br> f[0,0]:=searchrec.Name;<br> f[0,1]:=inttostr(searchrec.Size);<br> f[0,2]:=datetimetostr(filedatetodatetime(searchrec.Time ));<br> listitem:=listfile.wfile.Items.Add;<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add(f[0,1]);<br> listitem.SubItems.Add(f[0,2]);<br> shgetfileinfo(pchar(dirname+'/'+searchrec.Name ),0,fileinfo,sizeof(fileinfo),shgfi_icon);<br> listfile.image1.Picture.Icon.Handle:=fileinfo.hIcon;////返回文件图标<br> listfile.ImageList2.AddIcon(listfile.image1.Picture.Icon);<br> wfile.Items[wfile.Items.Count-1].ImageIndex:=imagelist2.Count -1;<br> end;<br> end;<br> end;<br> end;<br> findclose(searchrec);<br>end;<br>//////////////以上是查找文件的过程<br><br>procedure SelectNode(const Tx: string; Tree: TTreeView);<br>var www:Boolean;<br>begin<br> if Tx = '' then exit;<br> node3:=tree.Items.GetFirstNode;<br> while node3<>nil do<br> begin<br> if pathname+'/'+node3.Text = tx then<br> begin<br> //node.Expanded:=true;<br> //listfile.filedir(pathname+'/'+node1.Text,node1);<br> node3.Expanded:=true;<br> www:=true;<br> break;<br> end<br> else<br> begin<br> try<br> node3:=node3.GetNext;<br> except<br> showmessage(tx);<br> shellexecute(listfile.handle,nil,pchar(tx ),<br> nil,nil,sw_shownormal)<br> end;<br><br> end;<br> end;<br> if www=false then<br> shellexecute(listfile.handle,nil,pchar(tx ),<br> nil,nil,sw_shownormal)<br>end;<br>////////////以上是一个过程,处理鼠标在listviewh 双击事件过程<br>/////在树中查找 <br><br>procedure Tlistfile.FormCreate(Sender: TObject);<br>var i:integer;drivepath:string;<br> fname:string;<br> node:ttreenode;<br> rnode:ttreenode;<br>begin<br> shgetfileinfo(pchar('c:/'),0,fileinfo,sizeof(fileinfo),shgfi_icon);<br> listfile.image1.Picture.Icon.Handle:=fileinfo.hIcon;<br> listfile.ImageList1.AddIcon(listfile.image1.Picture.Icon);<br> listfile.ImageList2.AddIcon(listfile.image1.Picture.Icon);<br> shgetfileinfo(pchar('c:/Program Files'),0,fileinfo,sizeof(fileinfo),shgfi_icon);<br> listfile.image1.Picture.Icon.Handle:=fileinfo.hIcon;<br> listfile.ImageList1.AddIcon(listfile.image1.Picture.Icon);<br> shgetfileinfo(pchar('c:/Program Files'),0,fileinfo,sizeof(fileinfo),shgfi_icon);<br> listfile.image1.Picture.Icon.Handle:=fileinfo.hIcon;<br> listfile.ImageList1.AddIcon(listfile.image1.Picture.Icon);<br>///////////////////////////////////////////////<br>////因为有两个imagelist控件一个是树的,一个是listfile的,imagelist的图标库是空的。<br>////以上是为两个imagelist控件添加图标。以上的代码可以不要,但为了界面的美观,可以手工的为<br>////两个imagelist控件添加图标.<br>////////////////////以上添加的图标一个是硬盘的图标,一个是文件夹的图标.<br> dragacceptfiles(handle,true);<br> application.Title:='资源管理器';<br> for i:=0 to 25 do<br> begin<br> drivepath:=char(ord('A')+i)+':/';<br> case getdrivetype(pchar(drivepath))of<br> drive_removable:<br> //dir.Items.AddChild(nil,char(ord('A')+i)+':');<br> ;<br> drive_fixed:<br> begin<br> node:=dir.Items.AddChild(nil,char(ord('A')+i)+':');<br> rnode:=dir.Items.AddChild(node,'');<br> rnode.ImageIndex:=-1;<br> fname:=char(ord('A')+i)+':';<br> f[0,0]:=fname;<br> listitem:=wfile.Items.Add;<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add(f[0,1]);<br> end;<br> drive_remote:<br> begin<br> node:=dir.Items.AddChild(nil,char(ord('A')+i)+':');<br> rnode:=dir.Items.AddChild(node,'');<br> rnode.ImageIndex:=-1;<br> fname:=char(ord('A')+i)+':';<br> f[0,0]:=fname;<br> listitem:=wfile.Items.Add;<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add(f[0,1]);<br> end;<br> drive_cdrom:<br> begin<br> node:=dir.Items.AddChild(nil,char(ord('A')+i)+':');<br> rnode:=dir.Items.AddChild(node,'');<br> rnode.ImageIndex:=-1;<br> fname:=char(ord('A')+i)+':';<br> f[0,0]:=fname;<br> listitem:=wfile.Items.Add;<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add(f[0,1]);<br> end;<br> drive_ramdisk:<br> begin<br> node:=dir.Items.AddChild(nil,char(ord('A')+i)+':');<br> rnode:=dir.Items.AddChild(node,'');<br> rnode.ImageIndex:=-1;<br> fname:=char(ord('A')+i)+':';<br> f[0,0]:=fname;<br> listitem:=wfile.Items.Add;<br> listitem.Caption:=f[0,0];<br> listitem.SubItems.Add(f[0,1]);<br> end;<br> end;<br>////////////以上的循环返回机器上的所有硬盘<br> end;<br>end;<br><br>/////////////以上是窗体加载时的事件<br><br>procedure Tlistfile.dirCollapsed(Sender: TObject; Node: TTreeNode);<br>var I:integer;<br>begin<br> for i:=node.Count -1 downto 1 do<br> begin<br> node.Item .Delete ;<br> end;<br>end;<br>////////当treeview收缩时的事件<br><br>procedure Tlistfile.dirExpanded(Sender: TObject; Node: TTreeNode);<br>begin<br> panel(node);<br> names:=filename;<br> if filename<>'' then<br> begin<br> filedir(filename+node.Text ,node);<br> pathname:=filename+node.Text;<br> end<br> else<br> begin<br> filedir(node.Text ,node);<br> pathname:=node.Text;<br> end;<br> filename:='';<br>end;<br>///////treeview展开时的事件<br>/////以上的填充有两种,第一种就是我这种,第二种是在窗体加载时填充。<br>////第一种节省速度。<br>///////因为是网络传输,第一要考虑的就是速度,所以,我考虑第一种。<br>/////在节点展开是填充,收缩时删除节点,但只保留了一个。<br><br><br>procedure Tlistfile.WfileDblClick(Sender: TObject);<br>var i:integer;<br>begin<br> try<br> if wfile.ItemIndex=0 then<br> begin<br> node3.Collapse(true);<br> //node3.Expanded:=true;<br> node3.Parent.Selected:=true;<br> dir.OnClick(node3.Parent );<br> end<br> else<br> SelectNode(pathname+'/'+wfile.Selected.Caption,dir);<br> except<br> end;<br> // shellexecute(handle,nil,pchar(pathname+'/'+wfile.Selected.Caption ),<br> // nil,nil,sw_shownormal)<br><br>end;<br>/////////鼠标在listview上双击时<br><br>procedure Tlistfile.dirClick(Sender: TObject);<br>begin<br> zt.Panels[0].Text:='';<br> panel(dir.Selected);<br> names:=filename;<br> if filename<>'' then<br> begin<br> filedir(filename+dir.Selected.Text,dir.Selected);<br> pathname:=filename+dir.Selected.Text;<br> end<br> else<br> begin<br> filedir(dir.Selected.Text ,dir.Selected);<br> pathname:=dir.Selected.Text;<br> end;<br> filename:='';<br>end;<br>/////在treeview上单击时<br><br>procedure Tlistfile.N1Click(Sender: TObject);<br>begin<br> if deletefile(pathname+'/'+wfile.Selected.Caption) then<br> begin<br> filedir(pathname,dir.Selected);<br> zt.Panels[0].Text:='删除成功';<br> end<br> else<br> begin<br> zt.Panels[0].Text:='删除不成功';<br> end;<br>end;////处理在listview上删除一个对象是删除个文件<br><br>procedure Tlistfile.dirEdited(Sender: TObject; Node: TTreeNode;<br> var S: String);<br>begin<br> if RenameFile(pathname, names+s) then<br> zt.Panels[0].Text:='更名成功'<br> else<br> zt.Panels[0].Text:='更名不成功';<br>end;<br>//////在treeview上改名是更改对应的目录名<br><br>procedure Tlistfile.WfileEdited(Sender: TObject; Item: TListItem;<br> var S: String);<br>begin<br> if movefile(pchar(pathname+'/'+wfile.Selected.Caption),pchar(pathname+'/'+s)) then<br> zt.Panels[0].Text:='更名成功'<br> else<br> zt.Panels[0].Text:='更名不成功';<br>end;///////更改文件的文件名的事件<br><br>procedure Tlistfile.dirKeyUp(Sender: TObject; var Key: Word;<br> Shift: TShiftState);<br>Var<br> T:TSHFileOpStruct;<br> P:String;<br>begin<br> if key=46 then<br> begin<br> With T do<br> Begin<br> Wnd:=0;<br> wFunc:=FO_DELETE;<br> pFrom:=Pchar(pathname);<br> pTo:=nil;<br> fFlags:=FOF_ALLOWUNDO+FOF_NOCONFIRMATION+FOF_NOERRORUI;//标志表明允许恢复,无须确认并不显示出错信息<br> hNameMappings:=nil;<br> lpszProgressTitle:='正在删除文件夹...';<br> fAnyOperationsAborted:=False;<br> End;<br> if SHFileOperation(T)=0 then<br> begin<br> zt.Panels[0].Text:='删除完毕';<br> dir.Selected.Delete;<br> end<br> else<br> zt.Panels[0].Text:='删除不成功';<br> end;<br>end;//////删除节点时同时删除对应的目录,用户按了键盘上的[Delete]键.<br><br><br>procedure Tlistfile.D1Click(Sender: TObject);<br>var key: word;Shift: TShiftState;<br>begin<br> key:=46;<br> dir.OnKeyUp(sender,key,shift);<br>end;////点击tpopupmemu1的删除时。<br><br>procedure Tlistfile.R2Click(Sender: TObject);<br>begin<br> dir.Selected.EditText;<br>end;////////点击重命名时。<br><br>procedure Tlistfile.N3Click(Sender: TObject);<br>var node:ttreenode;<br> s:string;i:integer;<br>begin<br> i:=pos(dir.Selected.Text,pathname);<br> s:=pathname;<br> delete(s,i,length(dir.Selected.Text ));<br> //showmessage(s+'新建文件夹');<br> mkdir(s+'新建文件夹');<br> node:=dir.Items.AddChild(dir.Selected.Parent,'新建文件夹');<br> node.ImageIndex:=1;<br> node.SelectedIndex:=1;<br> node.EditText;<br>end;/////////点击新建文件夹时。<br><br>procedure Tlistfile.M1Click(Sender: TObject);<br>begin<br> mkdir(pathname+'/'+'新建文件夹');<br> listitem:=wfile.Items.Add;<br> listitem.Caption:='新建文件夹';<br> listitem.ImageIndex:=0;<br>end;///////在wfile上新建文件夹时.<br><br>procedure Tlistfile.N2Click(Sender: TObject);<br>var f:textfile;<br>begin<br> assignfile(f,pathname+'/'+'新建文件.Wxx');<br> rewrite(f);<br> closefile(f);<br> listitem:=wfile.Items.Add;<br> listitem.Caption:='新建文件.Wxx';<br> listitem.EditCaption;<br>end;////新建文件时。<br><br>procedure Tlistfile.N4Click(Sender: TObject);<br>begin<br> wfile.ViewStyle:=vsIcon;<br>end;/////////大图标<br><br>procedure Tlistfile.L1Click(Sender: TObject);<br>begin<br> wfile.ViewStyle:=vslist;<br>end;////////////列表<br><br>procedure Tlistfile.M2Click(Sender: TObject);<br>begin<br> wfile.ViewStyle:=vsSmallIcon;<br>end;///////////小图标<br><br>procedure Tlistfile.N7Click(Sender: TObject);<br>begin<br> wfile.ViewStyle:=vsReport;<br>end;///////////详细资料。<br><br>end.