If FindFirst or FindNext return a non-zero value, an error has occurred,
however an "error" in this case can simply mean there are no more files in
the directory. Use GetLastError to find out what the error code is, in this
case it will be ERROR_NO_MORE_FILES.
--
Wayne Niddery - WinWright Consulting
Delphi, C++Builder, JBuilder, InterDev --
http://home.ican.net/~wniddery/RADBooks.html
...remove chaff when replying...
"You know you've landed gear-up when it takes full power to taxi"
FindFirst maps to the API function FindFirstFile, FindNext to FindNextFile. Error
return values you can expect from these functions are (from windows.pas):
{ The system cannot find the file specified. }
ERROR_FILE_NOT_FOUND = 2;
{ The system cannot find the path specified. }
ERROR_PATH_NOT_FOUND = 3;
{ Access is denied. }
ERROR_ACCESS_DENIED = 5;
{ There are no more files. }
ERROR_NO_MORE_FILES = 18;
{ The device is not ready. }
ERROR_NOT_READY = 21;
The only ones you should usually get are either 2 (on FindFirst if no file
matches the mask) or 18 (on FindNext, when no more files matching the mask are
found). 21 will turn up if you try to search a diskette or CD drive with no disk
in it.
Example for a recursive directory scan:
{ excerpt from form declaration, form has a listbox1 for the
results, a label1 for progress, a button2 to start the scan,
an edit1 to get the search mask from, a button3 to stop
the scan. }
private
{ Private declarations }
FScanAborted: Boolean;
public
{ Public declarations }
Function ScanDrive( root, filemask: String; hitlist: TStrings ): Boolean;
Function TForm1.ScanDrive( root, filemask: String; hitlist: TStrings ): Boolean;
Function ScanDirectory( Var path: String ): Boolean;
Var
SRec: TSearchRec;
pathlen: Integer;
res: Integer;
Begin
label1.caption := path;
pathlen:= Length(path);
{ first pass, files }
res := FindFirst( path+filemask, faAnyfile, SRec );
If res = 0 Then
try
While res = 0 Do Begin
hitlist.Add( path + SRec.Name );
res := FindNext(SRec);
End;
finally
FindClose(SRec)
end;
Application.ProcessMessages;
Result := not (FScanAborted or Application.Terminated);
If not Result Then Exit;
{second pass, directories}
res := FindFirst( path+'*.*', faDirectory, SRec );
If res = 0 Then
try
While (res = 0) and Result Do Begin
If ((Srec.Attr and faDirectory) = faDirectory) and
(Srec.name[1] <> '.')
Then Begin
path := path + SRec.name + '\';
Result := ScanDirectory( path );
SetLength( path, pathlen );
End;
res := FindNext(SRec);
End;
finally
FindClose(SRec)
end;
End;
Begin
FScanAborted := False;
Screen.Cursor := crHourglass;
try
Result := ScanDirectory(root);
finally
Screen.Cursor := crDefault
end;
End;
procedure TForm1.Button2Click(Sender: TObject);
Var
ch: Char;
root: String;
Begin
root := 'C:\';
For ch := 'A' to 'Z' Do Begin
root[1] := ch;
Case GetDriveType( Pchar( root )) Of
DRIVE_FIXED, DRIVE_REMOTE:
If not ScanDrive( root, edit1.text, listbox1.items ) Then
Break;
End;
End;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin // aborts scan
fScanAborted := True;
end;
Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitely requested!
> [...]
> {second pass, directories}
> res := FindFirst( path+'*.*', faDirectory, SRec );
> If res = 0 Then
> try
> While (res = 0) and Result Do Begin
> If ((Srec.Attr and faDirectory) = faDirectory) and
> (Srec.name[1] <> '.')
(Srec.name <> '.') And (Srec.name <> '..')
> Then Begin
> [...]
Otherwise you wouldn't find dir-names starting with a dot, which
are quite common under *NIX and may be accessed via NFS or SMB
or ...
--
Matthias