unit WinForm;

////////////////////////////////////////////////////////////////////////////////
//  FileSystemWatcher Demo
//  Written by Giuseppe Madaffari, giuseppe@giumad.com
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

interface

uses
  System.Drawing, System.Collections, System.ComponentModel,
  System.Windows.Forms, System.Data, System.IO, System.Diagnostics;

type
  TWinForm = class(System.Windows.Forms.Form)
  {$REGION 'Designer Managed Code'}
  strict private
    /// <summary>
    /// Required designer variable.
    /// </summary>
    Components: System.ComponentModel.Container;
    Label1: System.Windows.Forms.Label;
    txtDir: System.Windows.Forms.TextBox;
    btnStart: System.Windows.Forms.Button;
    btnStop: System.Windows.Forms.Button;
    lbEvents: System.Windows.Forms.ListBox;
    Label2: System.Windows.Forms.Label;
    Label3: System.Windows.Forms.Label;
    txtMask: System.Windows.Forms.TextBox;
    chkWatchSubDir: System.Windows.Forms.CheckBox;
    chkSendNotification: System.Windows.Forms.CheckBox;
    LinkLabel1: System.Windows.Forms.LinkLabel;
    GroupBox1: System.Windows.Forms.GroupBox;
    Label4: System.Windows.Forms.Label;
    txtSMTP: System.Windows.Forms.TextBox;
    Label5: System.Windows.Forms.Label;
    txtMail: System.Windows.Forms.TextBox;
    chkAttachFile: System.Windows.Forms.CheckBox;
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    procedure InitializeComponent;
    procedure Button1_Click(sender: System.Object; e: System.EventArgs);
    procedure Button2_Click(sender: System.Object; e: System.EventArgs);
    procedure LinkLabel1_LinkClicked(sender: System.Object; e: System.Windows.Forms.LinkLabelLinkClickedEventArgs);
    procedure CheckBox2_CheckedChanged(sender: System.Object; e: System.EventArgs);
  {$ENDREGION}
  strict protected
    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    procedure Dispose(Disposing: Boolean); override;
  public
    Watcher: FileSystemWatcher;
    procedure WatchChanged(sender: System.Object; e: System.IO.FileSystemEventArgs);
    procedure WatchRenamed(sender: System.Object; e: System.IO.RenamedEventArgs);
    procedure CreateWatcher;
    procedure WatcherEvent(const Msg, FileName: string);
    procedure SendMail(const SmtpHost, Msg, ToMail: String;
      const FileName: String = '');
    constructor Create;
  end;

implementation
uses System.Web.Mail;

{$REGION 'Windows Form Designer generated code'}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
procedure TWinForm.InitializeComponent;
begin
  Self.Label1 := System.Windows.Forms.Label.Create;
  Self.txtDir := System.Windows.Forms.TextBox.Create;
  Self.btnStart := System.Windows.Forms.Button.Create;
  Self.btnStop := System.Windows.Forms.Button.Create;
  Self.lbEvents := System.Windows.Forms.ListBox.Create;
  Self.Label2 := System.Windows.Forms.Label.Create;
  Self.Label3 := System.Windows.Forms.Label.Create;
  Self.txtMask := System.Windows.Forms.TextBox.Create;
  Self.chkWatchSubDir := System.Windows.Forms.CheckBox.Create;
  Self.chkSendNotification := System.Windows.Forms.CheckBox.Create;
  Self.LinkLabel1 := System.Windows.Forms.LinkLabel.Create;
  Self.GroupBox1 := System.Windows.Forms.GroupBox.Create;
  Self.chkAttachFile := System.Windows.Forms.CheckBox.Create;
  Self.txtMail := System.Windows.Forms.TextBox.Create;
  Self.Label5 := System.Windows.Forms.Label.Create;
  Self.txtSMTP := System.Windows.Forms.TextBox.Create;
  Self.Label4 := System.Windows.Forms.Label.Create;
  Self.GroupBox1.SuspendLayout;
  Self.SuspendLayout;
  // 
  // Label1
  // 
  Self.Label1.Location := System.Drawing.Point.Create(16, 8);
  Self.Label1.Name := 'Label1';
  Self.Label1.Size := System.Drawing.Size.Create(100, 16);
  Self.Label1.TabIndex := 0;
  Self.Label1.Text := 'Directory to watch:';
  // 
  // txtDir
  // 
  Self.txtDir.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
  Self.txtDir.Location := System.Drawing.Point.Create(16, 24);
  Self.txtDir.Name := 'txtDir';
  Self.txtDir.Size := System.Drawing.Size.Create(344, 20);
  Self.txtDir.TabIndex := 1;
  Self.txtDir.Text := 'c:\';
  // 
  // btnStart
  // 
  Self.btnStart.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.btnStart.Location := System.Drawing.Point.Create(288, 80);
  Self.btnStart.Name := 'btnStart';
  Self.btnStart.TabIndex := 2;
  Self.btnStart.Text := 'Start watch';
  Include(Self.btnStart.Click, Self.Button1_Click);
  // 
  // btnStop
  // 
  Self.btnStop.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.btnStop.Enabled := False;
  Self.btnStop.Location := System.Drawing.Point.Create(373, 80);
  Self.btnStop.Name := 'btnStop';
  Self.btnStop.TabIndex := 3;
  Self.btnStop.Text := 'Stop watch';
  Include(Self.btnStop.Click, Self.Button2_Click);
  // 
  // lbEvents
  // 
  Self.lbEvents.Anchor := (System.Windows.Forms.AnchorStyles((((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Bottom) or System.Windows.Forms.AnchorStyles.Left) 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.lbEvents.Location := System.Drawing.Point.Create(16, 112);
  Self.lbEvents.Name := 'lbEvents';
  Self.lbEvents.Size := System.Drawing.Size.Create(432, 186);
  Self.lbEvents.TabIndex := 4;
  // 
  // Label2
  // 
  Self.Label2.Location := System.Drawing.Point.Create(16, 88);
  Self.Label2.Name := 'Label2';
  Self.Label2.Size := System.Drawing.Size.Create(100, 16);
  Self.Label2.TabIndex := 5;
  Self.Label2.Text := 'Watch events:';
  // 
  // Label3
  // 
  Self.Label3.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.Label3.Location := System.Drawing.Point.Create(368, 8);
  Self.Label3.Name := 'Label3';
  Self.Label3.Size := System.Drawing.Size.Create(72, 16);
  Self.Label3.TabIndex := 6;
  Self.Label3.Text := 'Mask:';
  // 
  // txtMask
  // 
  Self.txtMask.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.txtMask.Location := System.Drawing.Point.Create(368, 24);
  Self.txtMask.Name := 'txtMask';
  Self.txtMask.Size := System.Drawing.Size.Create(80, 20);
  Self.txtMask.TabIndex := 7;
  Self.txtMask.Text := '*.*';
  // 
  // chkWatchSubDir
  // 
  Self.chkWatchSubDir.Location := System.Drawing.Point.Create(16, 48);
  Self.chkWatchSubDir.Name := 'chkWatchSubDir';
  Self.chkWatchSubDir.TabIndex := 8;
  Self.chkWatchSubDir.Text := 'Watch subdirs';
  // 
  // chkSendNotification
  // 
  Self.chkSendNotification.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Bottom 
      or System.Windows.Forms.AnchorStyles.Left)));
  Self.chkSendNotification.Location := System.Drawing.Point.Create(16, 304);
  Self.chkSendNotification.Name := 'chkSendNotification';
  Self.chkSendNotification.Size := System.Drawing.Size.Create(200, 24);
  Self.chkSendNotification.TabIndex := 9;
  Self.chkSendNotification.Text := 'Send notification by email';
  Include(Self.chkSendNotification.CheckedChanged, Self.CheckBox2_CheckedChanged);
  // 
  // LinkLabel1
  // 
  Self.LinkLabel1.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Bottom 
      or System.Windows.Forms.AnchorStyles.Right)));
  Self.LinkLabel1.AutoSize := True;
  Self.LinkLabel1.Location := System.Drawing.Point.Create(344, 416);
  Self.LinkLabel1.Name := 'LinkLabel1';
  Self.LinkLabel1.Size := System.Drawing.Size.Create(109, 16);
  Self.LinkLabel1.TabIndex := 10;
  Self.LinkLabel1.TabStop := True;
  Self.LinkLabel1.Text := 'About this program...';
  Include(Self.LinkLabel1.LinkClicked, Self.LinkLabel1_LinkClicked);
  // 
  // GroupBox1
  // 
  Self.GroupBox1.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Bottom 
      or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
  Self.GroupBox1.Controls.Add(Self.chkAttachFile);
  Self.GroupBox1.Controls.Add(Self.txtMail);
  Self.GroupBox1.Controls.Add(Self.Label5);
  Self.GroupBox1.Controls.Add(Self.txtSMTP);
  Self.GroupBox1.Controls.Add(Self.Label4);
  Self.GroupBox1.Enabled := False;
  Self.GroupBox1.Location := System.Drawing.Point.Create(16, 328);
  Self.GroupBox1.Name := 'GroupBox1';
  Self.GroupBox1.Size := System.Drawing.Size.Create(312, 104);
  Self.GroupBox1.TabIndex := 11;
  Self.GroupBox1.TabStop := False;
  // 
  // chkAttachFile
  // 
  Self.chkAttachFile.Location := System.Drawing.Point.Create(8, 72);
  Self.chkAttachFile.Name := 'chkAttachFile';
  Self.chkAttachFile.Size := System.Drawing.Size.Create(280, 24);
  Self.chkAttachFile.TabIndex := 4;
  Self.chkAttachFile.Text := 'Attach watched files (use with care!)';
  // 
  // txtMail
  // 
  Self.txtMail.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
  Self.txtMail.Location := System.Drawing.Point.Create(80, 48);
  Self.txtMail.Name := 'txtMail';
  Self.txtMail.Size := System.Drawing.Size.Create(224, 20);
  Self.txtMail.TabIndex := 3;
  Self.txtMail.Text := 'mymail@mydomain.com';
  // 
  // Label5
  // 
  Self.Label5.Location := System.Drawing.Point.Create(8, 48);
  Self.Label5.Name := 'Label5';
  Self.Label5.Size := System.Drawing.Size.Create(64, 23);
  Self.Label5.TabIndex := 2;
  Self.Label5.Text := 'Email';
  // 
  // txtSMTP
  // 
  Self.txtSMTP.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top 
      or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
  Self.txtSMTP.Location := System.Drawing.Point.Create(80, 16);
  Self.txtSMTP.Name := 'txtSMTP';
  Self.txtSMTP.Size := System.Drawing.Size.Create(224, 20);
  Self.txtSMTP.TabIndex := 1;
  Self.txtSMTP.Text := 'smtp.mydomain.com';
  // 
  // Label4
  // 
  Self.Label4.Location := System.Drawing.Point.Create(8, 16);
  Self.Label4.Name := 'Label4';
  Self.Label4.Size := System.Drawing.Size.Create(64, 16);
  Self.Label4.TabIndex := 0;
  Self.Label4.Text := 'SMTP Host';
  // 
  // TWinForm
  // 
  Self.AutoScaleBaseSize := System.Drawing.Size.Create(5, 13);
  Self.ClientSize := System.Drawing.Size.Create(458, 439);
  Self.Controls.Add(Self.GroupBox1);
  Self.Controls.Add(Self.LinkLabel1);
  Self.Controls.Add(Self.chkSendNotification);
  Self.Controls.Add(Self.chkWatchSubDir);
  Self.Controls.Add(Self.txtMask);
  Self.Controls.Add(Self.Label3);
  Self.Controls.Add(Self.Label2);
  Self.Controls.Add(Self.lbEvents);
  Self.Controls.Add(Self.btnStop);
  Self.Controls.Add(Self.btnStart);
  Self.Controls.Add(Self.txtDir);
  Self.Controls.Add(Self.Label1);
  Self.FormBorderStyle := System.Windows.Forms.FormBorderStyle.FixedDialog;
  Self.Name := 'TWinForm';
  Self.StartPosition := System.Windows.Forms.FormStartPosition.CenterScreen;
  Self.Text := 'FileSystemWatcher Demo';
  Self.GroupBox1.ResumeLayout(False);
  Self.ResumeLayout(False);
end;
{$ENDREGION}

procedure TWinForm.Dispose(Disposing: Boolean);
begin
  if Disposing then
  begin
    if Components <> nil then
      Components.Dispose();
  end;
  inherited Dispose(Disposing);
end;

constructor TWinForm.Create;
begin
  inherited Create;
  //
  // Required for Windows Form Designer support
  //
  InitializeComponent;
  //
  // TODO: Add any constructor code after InitializeComponent call
  //
end;

procedure TWinForm.CheckBox2_CheckedChanged(sender: System.Object; e: System.EventArgs);
begin
  GroupBox1.Enabled := chkSendNotification.Checked;
end;

procedure TWinForm.LinkLabel1_LinkClicked(sender: System.Object; e: System.Windows.Forms.LinkLabelLinkClickedEventArgs);
begin
  MessageBox.Show('"Borland Delphi 8.0 for Microsoft .NET Framework" Sample Application'#13#10#13#10+
    'Written by Giuseppe Madaffari'#13#10+
    'email: giuseppe@giumad.com',
    'FileSystemWatcher');
end;

procedure TWinForm.Button2_Click(sender: System.Object; e: System.EventArgs);
begin
  Watcher.EnableRaisingEvents := False;
  
  btnStart.Enabled := True;
  btnStop.Enabled := False;
end;

procedure TWinForm.Button1_Click(sender: System.Object; e: System.EventArgs);
begin
  CreateWatcher;

  lbEvents.Items.Clear;

  Watcher.Path := txtDir.Text;
  Watcher.Filter := txtMask.Text;
  Watcher.IncludeSubdirectories := chkWatchSubDir.Checked;
  Watcher.EnableRaisingEvents := True;

  btnStart.Enabled := False;
  btnStop.Enabled := True;
end;

procedure TWinForm.WatchChanged(sender: TObject;
  e: System.IO.FileSystemEventArgs);
var
  Msg: string;
begin
  if e.ChangeType = WatcherChangeTypes.Changed then
    Msg := 'File "' + e.FullPath + '" has been modified'
  else if e.ChangeType = WatcherChangeTypes.Created then
    Msg := 'File "' + e.FullPath + '" has been created'
  else if e.ChangeType = WatcherChangeTypes.Deleted Then
    Msg := 'File "' + e.FullPath + '" has been deleted';

  WatcherEvent(Msg, e.FullPath);
end;

procedure TWinForm.CreateWatcher;
begin
  if not Assigned(Watcher) then
  begin
    Watcher := System.IO.FileSystemWatcher.Create;
    Watcher.NotifyFilter := NotifyFilters.FileName or
      NotifyFilters.Attributes;

    Include(Watcher.Changed, Self.WatchChanged);
    Include(Watcher.Created, Self.WatchChanged);
    Include(Watcher.Deleted, Self.WatchChanged);
    Include(Watcher.Renamed, Self.WatchRenamed);
  end
  else
    Watcher.EnableRaisingEvents := False;
end;

procedure TWinForm.WatchRenamed(sender: TObject;
  e: System.IO.RenamedEventArgs);
begin
  WatcherEvent('File "' + e.FullPath + '" has been renamed', e.FullPath);
end;

procedure TWinForm.SendMail(const SmtpHost, Msg, ToMail: String;
  const FileName: String = '');
var
  Mail: MailMessage;
  Attach: MailAttachment;
begin
  SmtpMail.SmtpServer := SmtpHost;

  Mail := MailMessage.Create;
  // change the following!
  Mail.From := 'filewatcher@mydomain.com';
  Mail.set_To(ToMail);  // can't use property TO because it's a Delphi Keyword!!
  Mail.Subject := 'FileWatcher notification';
  Mail.Body := Msg;
  if FileName <> '' then
  begin
    Attach := MailAttachment.Create(FileName);
    Mail.Attachments.Add(Attach);
  end;
  SmtpMail.Send(Mail);
  lbEvents.Items.Add('Nofitication sent by mail to ' + ToMail);
end;

procedure TWinForm.WatcherEvent(const Msg, FileName: string);
begin
  lbEvents.Items.Add(Msg);
  if chkSendNotification.Checked then
  begin
    if chkAttachFile.Checked then
      SendMail(txtSMTP.Text, Msg, txtMail.Text, FileName)
    else
      SendMail(txtSMTP.Text, Msg, txtMail.Text);
  end;
end;

end.
