Solved

FindFirst Only Add Files with selected extensions

Posted on 2009-05-10
4
462 Views
Last Modified: 2012-05-06
Hi, I'd like to be able to only add selected extensions into a listview while using findfirst.

where it says '*.*' I need it to be an array of like

only add that of mp3/jpg/txt/avi and everything else it wont add

so I can add more extensions to the list though the list needs to be editable also.
Function TigerSearchFolder( Path , FName : String; SubFolder , FileSize : Boolean ) : String;
Var
  Sr : TSearchRec;
  Res : Integer;
Begin
  Path := IncludeTrailingPathDelimiter( Path );
  Res := FindFirst( Path + FName , faAnyFile , Sr );
  While Res = 0 Do Begin
    Application.ProcessMessages;
    If ( Sr.Name <> '.' ) AND ( Sr.Name <> '..' ) Then Begin
      If DirectoryExists( Path + Sr.Name ) Then Begin
        If SubFolder Then Begin
          TigerSearchFolder( Path + Sr.Name , FName , SubFolder , FileSize);
        End;
      End Else Begin
        with form6.Listview1.Items.Add do begin
          Caption := path + Sr.Name;
          SubItems.Add(extractfilename(path + Sr.Name));
          SubItems.Add(extractFileExt(lowercase(path + Sr.Name)));
          //SubItems.Add(booltostr(DirectoryExists(path + Sr.Name)));
        end;
      End;
    End;
    Res := FindNext(Sr);
  End;
  FindClose(Sr);
End;
 
 
TigerSearchFolder('C:\; ,'*.*', true , true );

Open in new window

0
Comment
Question by:eNarc
  • 2
4 Comments
 
LVL 6

Assisted Solution

by:JosephGlosz
JosephGlosz earned 300 total points
ID: 24349450
one way is to create your own function that returns a boolean if the extension is one that you want to keep, as in:

function GoodExtension(S: string): boolean;
begin
  S := lowercase(S);  // to make comparison easier
  result := (pos('.avi',S) > 0) or (pos('.jpg',S) > 0) or
      (pos('.txt',S) > 0) or (pos('.mp3',S > 0);
end;

then, replace the last part of your posted code above with the following (adding the one line

"if GoodExtension(Sr.Name) then "

      End Else Begin
        with form6.Listview1.Items.Add do
          if GoodExtension(Sr.Name) then
          begin
          Caption := path + Sr.Name;
          SubItems.Add(extractfilename(path + Sr.Name));
          SubItems.Add(extractFileExt(lowercase(path + Sr.Name)));
          //SubItems.Add(booltostr(DirectoryExists(path + Sr.Name)));
        end;
      End;
 

0
 
LVL 6

Accepted Solution

by:
JosephGlosz earned 300 total points
ID: 24349461
actually, it would be best to literally extract the file extension instead of just a simple POS search.  So the GoodExtension function is better as:

function GoodExtension(S: string): boolean;
begin
  S := lowercase(ExtractFileExt(S));
  result := (S = '.avi) or (S = '.jpg') or (S = '.txt') or (S = '.mp3');
end;

0
 
LVL 12

Assisted Solution

by:rionroc
rionroc earned 100 total points
ID: 24349464
Hello

I hope that can help you.

http://delphi.about.com/library/weekly/code/filesearch.zip


Cheers!
0
 
LVL 37

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 100 total points
ID: 24352517
it would be event better if you supplied the listview as a parameter ...
it would make it form independant too

and why use a function if you don't assign a value to it ?
use a procedure instead, it will not give a warning, like function result may be undefined

this is a approach i would use (with a lbl to display the directory being searched)
procedure TigerSearchFolder(Path , FName: String; SubFolder, FileSize : Boolean; ValidExtensions: TStrings; ListView: TListView; lbl: TLabel);
const LVUpdate = 1;
var
  Sr : TSearchRec;
  LvChanges: Integer;
  procedure ListViewUpdate;
  begin
    Inc(LvChanges);
    if LvChanges mod LVUpdate = 0 then
    begin
      ListView.Items.EndUpdate;
      Application.ProcessMessages;
      ListView.Items.BeginUpdate;
    end;
  end;
  function ValidFile: boolean;
  begin
    Result := (ValidExtensions = nil) or
      (ValidExtensions.Count = 0) or
      (ValidExtensions.IndexOf(ExtractFileExt(SR.Name)) <> -1);
  end;
  procedure CheckItem;
  var li: TListItem;
  begin
    if (SR.Name <> '.') and (SR.Name <> '..') then
    begin
      if (SR.Attr and faDirectory = faDirectory) then
      begin
        if SubFolder then
          TigerSearchFolder(Path + Sr.Name, FName, SubFolder, FileSize, ValidExtensions, ListView, lbl);
      end
        else
      begin
        if ValidFile then
        begin
          li := Listview.Items.Add;
          li.Caption := path + Sr.Name;
          li.SubItems.Add(extractfilename(path + Sr.Name));
          li.SubItems.Add(extractFileExt(lowercase(path + Sr.Name)));
          ListViewUpdate;
        end;
      end;
    end;
  end;
Begin
  Path := IncludeTrailingPathDelimiter( Path );
  if FindFirst(Path + FName , faAnyFile , Sr ) = 0 then
  try
    lbl.Caption := Path;
    lbl.Update;
    CheckItem;
    while FindNext(Sr) = 0 do CheckItem;
  finally
    FindClose(Sr);
  end;
End;
 
procedure TForm1.Button1Click(Sender: TObject);
var List: TStrings;
begin
  List := TStringList.Create;
  try
    List.Add('.mp3');
    List.Add('.avi');
    ListView1.Items.BeginUpdate;
    try
      TigerSearchFolder('D:\','*.*', true , true, List, ListView1, Label1);
    finally
      ListView1.Items.EndUpdate;
    end;
  finally
    FreeAndNil(List);
  end;
end;

Open in new window

0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question