posted by Rodney Holiman on Tue 15th Jun 2004 19:19 UTC

"Monitor Class, Page 4/4"

Using The TDirectoryMonitor Class.

Using the TDirectoryMonitor class requires five steps.
The first step is to create an instance of the class.  The create constructor requires no parameters, so this is familiar to users of TstringList and other classes.
The next step is to set what events to watch for.  This is done by setting the value of the property ActionsToWatch property.
The third step is to set the value of the DirectoryToWatch property. The directory specified must exist; the class will not create it, and setting this property to a directory that does not exist will cause an error when the worker thread calls CreateFile. 
The fourth step is to assign an event handler to the OnDirectoryChange event.  The OnDirectoryChange event handler is where the user will decide what to do when a file notification event occurs.  The OnDirectoryChange event has the following definition :

procedure(Sender : TObject; Action : TDirectoryAction; FileName : String) Of Object;

Sender is the instance of the class that caused the event.  Action describes what event occurred.  The possible values are described in figure 10. FileName is the name of the file the action occurred on.
The last step is to call the Start method.  A complete example program describing these steps is shown in figure 11 (also available for download at my web site http://www.biggbytesoftware.com/rod/ReadDirectoryChangesDownloads.html.

daFileAdded The file in Filename has been added.
DaFileRemoved The file has been deleted.
DaFileModified The file has been changed.
DaFileRenamedOldName The file has been renamed and FileName is the old file name.
DaFileRenamedNewName The file has been renamed and FileName is the new file name.

Figure 10 – Action value descriptions.

{$WARN UNIT_PLATFORM OFF}
unit DirectoryMonitorDemoU;

interface

uses
  Windows, Messages, SysUtils, variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DirectoryMonitor;

type
  TfrmDemo = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    FDirMon : TDirectoryMonitor;
    procedure DirChange(Sender : TObject; Action : TDirectoryAction; FileName : String);
  public
    { Public declarations }
  end;

var
  frmDemo: TfrmDemo;

implementation
Uses
  FileCtrl;

{$R *.dfm}

procedure TfrmDemo.FormCreate(Sender: TObject);
begin
  FDirMon := TDirectoryMonitor.Create;
  FDirMon.OnDirectoryChange := DirChange;
  FDirMon.Options := [awChangeFileName,awChangeDirName,awChangeSize,awChangeLastWrite];
end;

procedure TfrmDemo.FormDestroy(Sender: TObject);
begin
  FDirMon.Free;
end;

procedure TfrmDemo.Button1Click(Sender: TObject);
var
  S : String;
begin
  SelectDirectory('Select A Directory To Monitor','',S);
  If S <> '' Then
    FDirMon.DirectoryToWatch := S;
  FDirMon.Start;
end;

procedure TfrmDemo.Button2Click(Sender: TObject);
begin
  FDirMon.Stop;
end;

procedure TfrmDemo.DirChange(Sender: TObject; Action: TDirectoryAction; FileName: String);
Const
  ActionDesc : Array[TDirectoryAction] Of String =
               ('FILE_ACTION_ADDED. The file %s was added to the directory.',
                'FILE_ACTION_REMOVED. The file %s was removed from the directory.',
                'FILE_ACTION_MODIFIED. The file %s was modified. 
'This can be a change in the time stamp or attributes.',
                'FILE_ACTION_RENAMED_OLD_NAME. The file %s was renamed, and this is the old name.',
                'FILE_ACTION_RENAMED_NEW_NAME The file %s was renamed and this is the new name.');

begin
  Memo1.Lines.Add(Format(ActionDesc[Action],[FileName]));
end;

end.

Figure 11 - A small sample program.

The Wrap Up

Monitoring a directory using ReadDirectoryChangesW can be a daunting task, but by wraping the complexity of it into an easy to use class I hope I have made the task a little less daunting.  BUT do take note, this class is not perfect nor was it meant to be. There needs to be more error handling and maybe some properties added before it would be production ready. I leave these things as an exercise for the reader.

About The Author
Rodney Holiman is a software developer and consultant specializing in Borland Delphi.


If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
Table of contents
  1. "Monitor Class, Page 1/4"
  2. "Monitor Class, Page 2/4"
  3. "Monitor Class, Page 3/4"
  4. "Monitor Class, Page 4/4"
e p (0)    16 Comment(s)