//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainForm.h"
#include <ctime>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
__fastcall TfrmMain::TfrmMain(TComponent* Owner) : TForm(Owner)
{
Abort = false;
}
//---------------------------------------------------------------------------
/*
Finds all files in the directory "Directory" of the type "FileSpec" and
adds them to "List". Example:
CatalogFiles("C:\Windows\System32", "*.exe", SomeList);
*/
int TfrmMain::CatalogFiles(const AnsiString& Directory, const AnsiString& FileSpec, TStringList& List)
{
TSearchRec finfo;
int done, count = 0;
AnsiString dir;
//Make sure there is a trailing "/"
dir = IncludeTrailingPathDelimiter(Directory);
// Display the current directory in the status bar
if (chkDisplayInStatusBar->Checked)
barStatus->SimpleText = Directory;
// Prime the search (See help on FindFirst/FindNext)
done = FindFirst(dir + FileSpec, faAnyFile, finfo);
// Until no more files match (or the user stopped it)
while ((done == 0) && (!Abort))
{
//if not ((finfo.Attr and faDirectory) <> 0) and (finfo.Name <> '.') and (finfo.Name <> '..') then begin
// Ignore current directory and parent directory
if ((finfo.Name != ".") && (finfo.Name != ".."))
{
// Add the filename to the list
List.Add(finfo.Name);
// Inserting at the front of the list or adding to the back?
if (chkInsertAtFront->Checked)
lstFiles->Items->Insert(0, Directory + finfo.Name);
else
lstFiles->Items->Add(Directory + finfo.Name);
// Update the UI (After every file)
if (grpUpdateFrequency->ItemIndex == 0)
lblCount->Caption = IntToStr(lstFiles->Count);
count++;
}
// Next match?
done = FindNext(finfo);
// Yield
Application->ProcessMessages();
}
// Done searching
FindClose(finfo);
return count;
}
/*
Finds all files in the directory "Directory" of the type "FileSpec" and
adds them to "List". If "IncludeSubdirectories" is true, it will call
itself recursively. Example:
FindFiles("C:\Windows\System32", "*.exe", SomeList, true);
The real work is done by the CatalogFiles above.
*/
int TfrmMain::FindFiles(const AnsiString& Directory, TStringList& FileSpecs, TStringList& List, bool IncludeSubdirectories)
{
TSearchRec finfo;
int done, count = 0;
AnsiString filespec, dir, subdir, dirspec;
//Make sure there is a trailing "/"
dir = IncludeTrailingPathDelimiter(Directory);
// Always search for all when looking for directories
dirspec = dir + "*.*";
// Get all files for each spec
for (int i = 0; i < FileSpecs.Count; i++)
{
// Get the next filespec
filespec = FileSpecs[i];
// Find matching files
count += CatalogFiles(dir, filespec, List);
}
// Always search for *.* when looking for directories
if (IncludeSubdirectories)
{
// Find the first one that matches
done = FindFirst(dirspec, faAnyFile, finfo);
// While there are more files that match (and the user doesn't abort)
while ((done == 0) && (!Abort))
{
// If it's a directory (not current or parent), traverse it
if (((finfo.Attr & faDirectory) != 0) && (finfo.Name != ".") && (finfo.Name != ".."))
{
subdir = Format("%s%s", ARRAYOFCONST((dir, finfo.Name)));
count += FindFiles(subdir, FileSpecs, List, IncludeSubdirectories);
}
// Update the UI (After every directory)
if (grpUpdateFrequency->ItemIndex == 1)
lblCount->Caption = IntToStr(lstFiles->Count);
Application->ProcessMessages();
// Next file
done = FindNext(finfo);
}
FindClose(finfo);
}
return count;
}
void __fastcall TfrmMain::btnFindClick(TObject *Sender)
{
TStringList *list = new TStringList();
TStringList *filespecs = new TStringList();
filespecs->Add(lstFileSpecs->Text);
Abort = false;
lstFiles->Clear();
lblCount->Caption = "";
lblTime->Caption = "Working...";
barStatus->SimpleText = "Searching...";
std::clock_t start = std::clock();
if (chkUseUpdate->Checked)
lstFiles->Items->BeginUpdate();
int count = FindFiles(lstDirectory->Text, *filespecs, *list, chkIncludeSubdirectories->Checked);
if (chkUseUpdate->Checked)
lstFiles->Items->EndUpdate();
std::clock_t end = std::clock();
barStatus->SimpleText = "Done.";
lblTime->Caption = Format("%d ms", ARRAYOFCONST((end - start)));
// Update UI (After complete)
lblCount->Caption = IntToStr(count);
delete list;
delete filespecs;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnStopClick(TObject *Sender)
{
Abort = true;
}
//---------------------------------------------------------------------------
/*
When an item in the tree is double-clicked, open it with the appropriate
application. See MSDN for more information on ShellExecute and associated
functions, e.g. ShellExecuteEx, and the ShellAPI in shellapi.h.
*/
void __fastcall TfrmMain::lstFilesDblClick(TObject *Sender)
{
// If something is double-clicked, it will be the selected item
int index = lstFiles->ItemIndex;
if (index == -1)
return; // shouldn't happen
AnsiString str = lstFiles->Items->Strings[index];
ShellExecute(Handle, "open", str.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------