这几天都在调试一个问题就是用SHFileOperation函数删除文件夹总是出现如下问题
呵呵,很头疼,那个程序在使用呢?肯定是我自己的程序了。自己找了找程序,觉得没问题,就去看删除文件夹的函数,代码如下:
1
function
DeleteDirectory(DeleteStr: String): Boolean;
2 var
3 f: TSHFILEOPSTRUCT;
4 begin
5 FillChar(f, SizeOf(TSHFILEOPSTRUCT, 0 );
6 with f do
7 begin
8 fFlags : = FOF_NOCONFIRMATION; // 这里的属性很多,我就不说了,有需要的自己查查看
9 Wnd : = 0 ;
10 wFunc : = FO_DELETE; // 这里当然是使用删除的属性了
11 pFrom : = PChar(DeleteStr + # 0 ); // 这里网上很多人提到要在最后加一个# 0 ,否则会报其他错误
12 pTo : = nil ;
13 end ;
14 Result : = (SHFileOperation(f) = 0);
2 var
3 f: TSHFILEOPSTRUCT;
4 begin
5 FillChar(f, SizeOf(TSHFILEOPSTRUCT, 0 );
6 with f do
7 begin
8 fFlags : = FOF_NOCONFIRMATION; // 这里的属性很多,我就不说了,有需要的自己查查看
9 Wnd : = 0 ;
10 wFunc : = FO_DELETE; // 这里当然是使用删除的属性了
11 pFrom : = PChar(DeleteStr + # 0 ); // 这里网上很多人提到要在最后加一个# 0 ,否则会报其他错误
12 pTo : = nil ;
13 end ;
14 Result : = (SHFileOperation(f) = 0);
15 end;
来回测试很多次,换了很多属性,还是这个错误 ,回头想了一下,被一个程序占用,肯定是我自己的程序了
所以又检查扫描文件夹目录的过程,代码如下:
1
procedure
TForm1.SCanTreeView;
2 var
3 DirectoryStr: String;
4 DirSr, FileSr: TSearchRec;
5 FileStrList, StrList: TStringList;
6 I: Integer;
7 DirNode, FileNode: TTreeNode;
8 begin
9 for I : = RzTreeView1.Items.Count - 1 downto 0 do
10 begin
11 if RzTreeView1.Items[i].Level <> 0 then
12 begin
13 RzTreeView1.Items[i].Delete;
14 end ;
15 end ;
16 DirectoryStr : = ExtractFilePath(ParamStr( 0 ));
17 StrList : = TStringList.Create;
18 FileStrList : = TStringList.Create;
19 if FindFirst(DirectoryStr + ' * ' , faDirectory, DirSr) = 0 then
20 begin
21 Repeat
22 if ((DirSr.Attr and faDirectory) = faDirectory) and ((DirSr.Name <> ' . ' ) and (DirSr.Name <> ' .. ' )) then
23 begin
24 DirNode : = RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
25 DirNode.ImageIndex : = 1 ;
26 DirNode.SelectedIndex : = 1 ;
27
28 if FindFirst(DirectoryStr + DirSr.Name + ' \*.cks ' , faAnyFile, FileSr) = 0 then
29 begin
30 Repeat
31 FileStrList.Delimiter : = ' \ ' ;
32 FileStrList.DelimitedText : = FileSr.Name;
33 FileNode : = RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count - 1 ], ' .cks ' , '' , [rfReplaceAll]));
34 FileNode.ImageIndex : = 6 ;
35 FileNode.SelectedIndex : = 6 ;
36 Until FindNext(FileSr) <> 0 ;
37 end ;
38 end ;
39 Until FindNext(DirSr) <> 0 ;
40 end ;
41 FindClose(DirSr);
42 FindClose(FileSr);
43 StrList.Free;
44 FileStrList.Free;
45 RzTreeView1.FullExpand;
2 var
3 DirectoryStr: String;
4 DirSr, FileSr: TSearchRec;
5 FileStrList, StrList: TStringList;
6 I: Integer;
7 DirNode, FileNode: TTreeNode;
8 begin
9 for I : = RzTreeView1.Items.Count - 1 downto 0 do
10 begin
11 if RzTreeView1.Items[i].Level <> 0 then
12 begin
13 RzTreeView1.Items[i].Delete;
14 end ;
15 end ;
16 DirectoryStr : = ExtractFilePath(ParamStr( 0 ));
17 StrList : = TStringList.Create;
18 FileStrList : = TStringList.Create;
19 if FindFirst(DirectoryStr + ' * ' , faDirectory, DirSr) = 0 then
20 begin
21 Repeat
22 if ((DirSr.Attr and faDirectory) = faDirectory) and ((DirSr.Name <> ' . ' ) and (DirSr.Name <> ' .. ' )) then
23 begin
24 DirNode : = RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
25 DirNode.ImageIndex : = 1 ;
26 DirNode.SelectedIndex : = 1 ;
27
28 if FindFirst(DirectoryStr + DirSr.Name + ' \*.cks ' , faAnyFile, FileSr) = 0 then
29 begin
30 Repeat
31 FileStrList.Delimiter : = ' \ ' ;
32 FileStrList.DelimitedText : = FileSr.Name;
33 FileNode : = RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count - 1 ], ' .cks ' , '' , [rfReplaceAll]));
34 FileNode.ImageIndex : = 6 ;
35 FileNode.SelectedIndex : = 6 ;
36 Until FindNext(FileSr) <> 0 ;
37 end ;
38 end ;
39 Until FindNext(DirSr) <> 0 ;
40 end ;
41 FindClose(DirSr);
42 FindClose(FileSr);
43 StrList.Free;
44 FileStrList.Free;
45 RzTreeView1.FullExpand;
46 end;
看完这个过程不知道大家有没有发现错误?呵呵,我也是测试了好久才发现这个错误
就是没有在FindNext(FileSr)<> 0 之后没有用CloseHandle(FileSr)关闭, 导致之前扫描的文件都被占用,所以每次删除都报错,这是一个很细微的错误,希望大家不要像我一样不仔细
正确的代码如下:
2
procedure
TForm1.SCanTreeView;
3 var
4 DirectoryStr: String;
5 DirSr, FileSr: TSearchRec;
6 FileStrList, StrList: TStringList;
7 I: Integer;
8 DirNode, FileNode: TTreeNode;
9 begin
10 for I : = RzTreeView1.Items.Count - 1 downto 0 do
11 begin
12 if RzTreeView1.Items[i].Level <> 0 then
13 begin
14 RzTreeView1.Items[i].Delete;
15 end ;
16 end ;
17 DirectoryStr : = ExtractFilePath(ParamStr( 0 ));
18 StrList : = TStringList.Create;
19 FileStrList : = TStringList.Create;
20 if FindFirst(DirectoryStr + ' * ' , faDirectory, DirSr) = 0 then
21 begin
22 Repeat
23 if ((DirSr.Attr and faDirectory) = faDirectory) and ((DirSr.Name <> ' . ' ) and (DirSr.Name <> ' .. ' )) then
24 begin
25 DirNode : = RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
26 DirNode.ImageIndex : = 1 ;
27 DirNode.SelectedIndex : = 1 ;
28
29 if FindFirst(DirectoryStr + DirSr.Name + ' \*.cks ' , faAnyFile, FileSr) = 0 then
30 begin
31 Repeat
32 FileStrList.Delimiter : = ' \ ' ;
33 FileStrList.DelimitedText : = FileSr.Name;
34 FileNode : = RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count - 1 ], ' .cks ' , '' , [rfReplaceAll]));
35 FileNode.ImageIndex : = 6 ;
36 FileNode.SelectedIndex : = 6 ;
37 Until FindNext(FileSr) <> 0 ;
38 CloseHandle(FileSr); //注意这里,关闭掉FileSr;
39 end ;
40 end ;
41 Until FindNext(DirSr) <> 0 ;
42 end ;
43 FindClose(DirSr);
44 FindClose(FileSr);
45 StrList.Free;
46 FileStrList.Free;
47 RzTreeView1.FullExpand;
3 var
4 DirectoryStr: String;
5 DirSr, FileSr: TSearchRec;
6 FileStrList, StrList: TStringList;
7 I: Integer;
8 DirNode, FileNode: TTreeNode;
9 begin
10 for I : = RzTreeView1.Items.Count - 1 downto 0 do
11 begin
12 if RzTreeView1.Items[i].Level <> 0 then
13 begin
14 RzTreeView1.Items[i].Delete;
15 end ;
16 end ;
17 DirectoryStr : = ExtractFilePath(ParamStr( 0 ));
18 StrList : = TStringList.Create;
19 FileStrList : = TStringList.Create;
20 if FindFirst(DirectoryStr + ' * ' , faDirectory, DirSr) = 0 then
21 begin
22 Repeat
23 if ((DirSr.Attr and faDirectory) = faDirectory) and ((DirSr.Name <> ' . ' ) and (DirSr.Name <> ' .. ' )) then
24 begin
25 DirNode : = RzTreeView1.Items.AddChild(RzTreeView1.Items[ 0 ], DirSr.Name);
26 DirNode.ImageIndex : = 1 ;
27 DirNode.SelectedIndex : = 1 ;
28
29 if FindFirst(DirectoryStr + DirSr.Name + ' \*.cks ' , faAnyFile, FileSr) = 0 then
30 begin
31 Repeat
32 FileStrList.Delimiter : = ' \ ' ;
33 FileStrList.DelimitedText : = FileSr.Name;
34 FileNode : = RzTreeView1.Items.AddChild(DirNode, StringReplace(FileStrList[FileStrList.Count - 1 ], ' .cks ' , '' , [rfReplaceAll]));
35 FileNode.ImageIndex : = 6 ;
36 FileNode.SelectedIndex : = 6 ;
37 Until FindNext(FileSr) <> 0 ;
38 CloseHandle(FileSr); //注意这里,关闭掉FileSr;
39 end ;
40 end ;
41 Until FindNext(DirSr) <> 0 ;
42 end ;
43 FindClose(DirSr);
44 FindClose(FileSr);
45 StrList.Free;
46 FileStrList.Free;
47 RzTreeView1.FullExpand;
48 end;
在网上很多人说SHFileOperation这个函数很不好用,刚开始我也这么认为,但是当我真正找到原因之后,才知道是自己学艺不精,呵呵
这里特给自己做一个记号,也给在网上很多人,在这个问题上没有找到答案的朋友一个提示,看看是不是和我一样的错误,最终能够解决问题
也请大神们多多指教