Examples Delphi

Title: How to realize a ChangeFinder
Question: Where or when a modification has changed an existing file or a new one, the ChangeFinder can show the files in a listview by searching the now system date on your drives.
The changed files are shown with attributes, size and path names rather than numbers making it easier to see what's going on on your storage system or hard drive.
Answer:
This should make it easier to determine which files had changed and diminish the chance that a change is causing an undiscovered impact (spyware, caching, integrity etc.).
First we need a class:
type
TChangeFinder = class
private
nYear,
nMonth,
nDay: word;
dflistView: TListView;
protected
procedure ShowFiles (Showpath: string; sr: TSearchRec);
public
constructor prepList_and_Date(alistView: TListView);
procedure SearchDirectories(path: string; const fname: string);
end;
The call from the client needs an instance of a 3 column TListView and the choosen drive letters:
procedure TmainForm1.cfinderClick(Sender: TObject);
//tshChangefind: TTabSheet, pageindex=5, event= onShow
var drive: string[20];
mycf: TChangeFinder;
begin
screen.cursor:=crHourglass;
drive:= dcbHD.Drive;
drive:= drive + ':';
mycf:= TChangeFinder.prepList_and_Date(mainForm1.view);
mycf.SearchDirectories(drive + '\','*.*');
mycf.Free;
screen.cursor:=crDefault;
end;
The form independent unit itself scans for all files with the system date of today or now so you get a list in a listview for a filechange detection system for Web Servers, protocol machines, loggers, databases or something else useful ;).
Implementation of the unit changefinder:
------------------------------------------------------------
constructor TChangeFinder.prepList_and_Date(alistView: TListView);
begin
inherited Create;
dflistView:= alistView;
decodedate(date, nYear, nMonth, nDay);
with alistView do begin
columns[0].Caption:= 'Filename';
columns[1].Caption:= 'Size';
columns[2].Caption:= 'Attr';
end;
with alistView.Items do begin
BeginUpdate;
Clear;
EndUpdate;
end;
end;
procedure TChangeFinder.ShowFiles(Showpath: string; sr: TSearchRec);
var
arcdisp: string[9];
dateRec: TDateTime;
lenStr,
fname,
fext: string;
itNewItem: TListItem;
AYear, AMonth, ADay: Word;
begin
if sr.Attr IN [$8..$F, $28..$2F] then begin
if Pos('.', sr.Name) 0 then
Delete(sr.Name, Pos('.', sr.Name), 1);
end;
if (Pos('.', sr.Name) 0) AND (Length(sr.Name) 0) then begin
fname:= Copy(sr.Name, 1, Pos('.', sr.Name) - 1);
fext:= sr.Name;
Delete(fext, 1, Pos('.', fext));
end else begin
fname:= sr.Name;
fext:= ' ';
end;
arcdisp:= ' ';
{$WARN SYMBOL_PLATFORM OFF}
if sr.Attr AND faArchive = faArchive then arcdisp[1] := 'A';
if sr.Attr AND faReadOnly = faReadOnly then arcdisp[2] := 'R';
if sr.Attr AND faHidden = faHidden then arcdisp[3] := 'H';
if sr.Attr AND faSysFile = faSysFile then arcdisp[4] := 'S';
{$WARN SYMBOL_PLATFORM ON}
//attr. 8..15, 40..47
if NOT (sr.Attr IN [$8..$F, $28..$2F]) then
Str(sr.Size, lenStr);
if NOT (sr.Attr IN [$8..$F, $28..$2F]) then begin
//check the system now date!
dateRec:= FileDatetoDateTime(sr.Time);
DecodeDate(dateRec, AYear, AMonth, ADay);
if (ADay = nDay) AND (AYear = nYear) AND (AMonth = nMonth) then
begin
if Showpath[Length(Showpath)] = '\' then
Delete(Showpath, Length(Showpath), 1);
itNewItem:= dflistView.Items.insert(0);
itNewItem.Caption:= Showpath + '\' + fname+ '.' + fext;
itNewItem.SubItems.Add(lenStr);
itNewItem.SubItems.Add(arcdisp);
end;
end;
end;
procedure TChangeFinder.SearchDirectories(path: string; const fname: string);
var
SRecord : TSearchRec;
locShowpath: string;
begin
(* search of files: *)
if Length(path) 0 then
if path[Length(path)] '\' then
path := path + '\';
SRecord.Name := '';
if FindFirst(path + fname, faAnyfile MOD faDirectory, SRecord) = 0
then begin
//Showpath:= ' . ';
if SRecord.Name '' then begin
if Length(path) 3 then
locShowpath:= Copy(path, 1, Length(path) - 1)
else locShowpath:= path;
end;
try
repeat
//attr 0..14, 32..46
if SRecord.Attr IN [$0..$E, $20..$2E] then
ShowFiles(locShowpath, SRecord);
until FindNext(SRecord) 0;
finally
FindClose(SRecord);
end;
end;
//search of dir. including hidden dirs!
if FindFirst(path + '*.*', faDirectory or faHidden, SRecord) = 0
then begin
try
repeat
if (SRecord.Attr AND faDirectory 0) AND
(SRecord.Name[1] '.') then
//recursion to get subdirectories
SearchDirectories(path + SRecord.Name, fname);
until FindNext(SRecord) 0;
finally
FindClose(SRecord);
end;
end;
end;
end.