Find File

Does anyone have a file find function?  I want it to look for a file and then return back to me the path information.  I also need something that can look at more than one drive...including network drives...Doesn't need to look at the CD or floppy. (maby as an option)
Thanks
LVL 1
GreedyAsked:
Who is Participating?
 
ssiteConnect With a Mentor Commented:
Doesn't delphi have a filesearch function ? Other than that, you should just write a recursive function to do that. If you want, I can e-mail you some sources.
0
 
GreedyAuthor Commented:
Yeah, that'll work but I need something that will give me all the valid drive letters too.
0
 
JimBob091197Commented:
Hi Greedy,

I'm not wanting ssite's points, but this is how you can get all the valid drive letters:

var
  LogicalDrives, i: Integer;
begin
  LogicalDrives := GetLogicalDrives;
  for i := 0 to 25 do
    if (LogicalDrives and (Round(Power(2, i))) > 0) then
      ShowMessage(Chr(65 + i) + ': is a valid drive.');
end;

(The Power function is defined in Delphi's Math unit.)

Cheers,
JB
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

 
ssiteCommented:
You can also just use this function to find out if the drive is ready for all 26 available letters

function DiskInDrive(Drive: Char): Boolean;
var
   ErrorMode: word;
begin
   if Drive in ['a'..'z'] then Dec(Drive, $20);
   if not (Drive in ['A'..'Z']) then
     raise EConvertError.Create('Not a valid drive ID');
   ErrorMode := SetErrorMode(SEM_FailCriticalErrors);
   try
    if DiskSize(Ord(Drive) - $40) = -1 then
      Result := False
    else
      Result := True;
    finally
      SetErrorMode(ErrorMode);
    end;
end;

0
 
GreedyAuthor Commented:
Is there an easy way to tell FileSearch to recurse the subdirectoris...Acctually this kinda sucks because I'm writing a ton of code to do this...I'm going to open the question back up to see if someone already has a unit built that I can use...if they don't and I have to write one myself I'll give it anyone that wants it and give you the points there ssite.  Right now I'm taking most of my code from the Filectrl unit to do the recurse and the drive type validation. (dtFixed, dtNetwork)
Thanks for the help  




0
 
GreedyAuthor Commented:
oh ssite...you said you have some source...can you send it to
flicky@frottage.com

0
 
GreedyAuthor Commented:
Not that I need it for what I'm doing but do you know how to have it look for wild cards too.  Like *.exe...I'll leave the question locked until I get a responce form you there ssite.

0
 
ssiteCommented:
Unfortunately, it's weekend here in israel and I'm away from my office machine. Just look up delphi's findfirst/findnext example, and use your wildcards there. The general code should check to see if the filename is not '.' or '..'  Then you should check the attribute to see if it's a directory. If so - recall the functions with the new dir specification. If it's a file - you found it.

Good Luck
0
 
pjdbCommented:
This code determine the total size of the files of the directory (passed in the rep parameter) and recurse sub dir if recurse is true. You need to have "windows" in the uses clause after the "sysutils" because there is a double declaration for FindClose.

function det_taille(rep:string; recurse:boolean):longint;
var
  FileHandle:THandle;
  FindData:TWin32FindData;
begin
  rep:=rep + '\';
  result:=0;
  FileHandle:=FindFirstFile(pchar(rep + '*.*'), FindData);
  if FileHandle<>invalid_handle_value then
    repeat
      with FindData do
        if (dwFileAttributes and file_attribute_directory)=0 then
          result:=result + (nFileSizeHigh * maxdword) + nFileSizeLow
        else
          if recurse and (cFileName[0]<>#46) then
            result:=result + det_taille(rep + cFileName, recurse);
    until not findnextfile(FileHandle, FindData);
  findclose(FileHandle);
end;      {det_taille}

JDB
0
 
GreedyAuthor Commented:
I think I got it...anyone think they can make the code smaller...
Feal free to use this as you wish...most of it is taken from the filectrl.pas file...It's rather quick compaired to the start button's find file.  to test it I have a EditBox a Button a TAnimate (makes it pretty) and a ListBox.  THANKS Everyone for the help.  I'll give you the points, ssite, on monday so everyone can partake of the code witout haveing to pay 5 points.  

procedure TForm1.Button1Click(Sender: TObject);
var
  DriveNum, DirCounter, ListPointer : Integer;
  DriveChar : Char;
  DriveBits : set of 0..25;
  DirectoryList : TStringList;

  procedure ReadDirectoryNames(const ParentDirectory: string);
  var
    Status: Integer;
    SearchRec: TSearchRec;

    function SlashSep(const Path, S: String): String;
    begin
      if AnsiLastChar(Path)^ <> '\' then
        Result := Path + '\' + S
      else
        Result := Path + S;
    end;

  begin
    Status := FindFirst(SlashSep(ParentDirectory, '*.*'), faDirectory, SearchRec);
    try
      while Status = 0 do
      begin
        if (SearchRec.Attr and faDirectory = faDirectory) then
        begin
          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
            DirectoryList.Add(SlashSep(ParentDirectory, SearchRec.Name));
        end;
        Status := FindNext(SearchRec);
      end;
    finally
      FindClose(SearchRec);
    end;
  end;

begin
  ListBox1.Items.Clear;
  Animate1.Visible := True;
  Animate1.Active := True;
  Integer(DriveBits) := GetLogicalDrives;
  For DriveNum := 0 to 25 do
  begin
    if not (DriveNum in DriveBits) then Continue;
    begin
      DriveChar := Char(DriveNum + Ord('a'));
      if FileCtrl.TDriveType(GetDriveType(PChar(DriveChar + ':\'))) in [FileCtrl.dtFixed, FileCtrl.dtNetwork] then
      begin
        DirectoryList := TStringList.Create;
        DirectoryList.Add(DriveChar + ':');
        ListPointer := 0;
        While ListPointer <= DirectoryList.Count-1 do
        begin
          ReadDirectoryNames(DirectoryList.Strings[ListPointer]);
          inc(ListPointer);
        end;
        For DirCounter := 1 to DirectoryList.Count -1 do
        begin
          if Length(FileSearch(Edit1.Text, (DirectoryList.Strings[DirCounter] + '\'))) <> 0 then
            ListBox1.Items.Add(DirectoryList.Strings[DirCounter] + '\' + Edit1.Text);
        end;
        DirectoryList.Free;
      end;
    end;
  end;
  ListBox1.Items.BeginUpDate;
  ListBox1.Sorted := True;
  ListBox1.Items.EndUpdate;
  Animate1.Active := False;
  Animate1.Visible := False;
end;

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.