IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Nono40.developpez.com
Le petit coin du web de Nono40
SOURCES TESTS DELPHI WIN32 AUTOMATISMES DELPHI .NET QUICK-REPORT
Retour à l'accueil
17 - SURVEILLANCE D'UN REPERTOIRE

PRÉSENTATION : Programme d'exemple de l'utilisation des notifications de modification de Windows.
ZIP : Téléchargez le zip APERÇUS :

NOTES : Ce programme montre l'utilisation des notifications de modification de répertoire. C'est utile pour suivre les modifications apportées aux fichiers dans un répertoire.
Par exemple si vous affichez la liste de certains fichiers dans une ListBox ou un TreeView, il est possible de mettre la liste à jour seulement quand un fichier est ajouté et/ou supprimé.
La surveillance est effectuée dans un autre Thread afin de ne pas bloquer l'application principale.

CODE :
Unit Unit1;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

Type
  TForm1 = Class(TForm)
    Memo1: TMemo;
    Panel1: TPanel;
    Label1: TLabel;
    Edit1: TEdit;
    Button1: TButton;
    Procedure FormCreate(Sender: TObject);
    Procedure FormClose(Sender: TObject; Var Action: TCloseAction);
    Procedure Button1Click(Sender: TObject);
  Private
    { Déclarations privées }
  Public
    { Déclarations publiques }
  End;

  TThreadSurveillance = Class(TThread)
  Private
    { Déclarations privées }
    ListeAjouts            : TStrings;
    HandleNotification     : THandle;
    CheminEnCours          : String;
    DateHeureVerification  : TDateTime;
    Procedure MiseAJourListe;
  Protected
    Procedure Execute; override;
  End;

Var
  Form1: TForm1;

Implementation

{$R *.dfm}

Var CheminASurveiller     : String              = '';
    ThreadSurveillance    : TThreadSurveillance = Nil;

Procedure TThreadSurveillance.Execute;
Var Chemin  :Array[0..255]Of Char;
    Infos   :TSearchRec;
Begin
  // Initialisation ds données du Thread
  ListeAjouts           := TStringList.Create;
  HandleNotification    := INVALID_HANDLE_VALUE;
  CheminEnCours         := '';

  // Boucle pincipale du Thread
  While Not Terminated Do
  Begin
    // Le chemin demandé à changé => On change la surveillance
    If CheminASurveiller<>CheminEnCours
    Then Begin
      ListeAjouts.Clear;

      // Une demande est en cours, on libère le Handle
      If HandleNotification<>INVALID_HANDLE_VALUE
      Then Begin
        FindCloseChangeNotification(HandleNotification);
        HandleNotification:=INVALID_HANDLE_VALUE;
        ListeAjouts.Add('<FIN>');
      End;

      // Prise en compte de la nouvelle demande
      CheminEnCours:=CheminASurveiller;
      If CheminEnCours<>''
      Then Begin
        // Suppression du '\' final
        CheminEnCours := ExcludeTrailingPathDelimiter(CheminEnCours);
        // Création de la demande de notification
        HandleNotification := FindFirstChangeNotification(
          StrPCopy(Chemin,CheminEnCours),     // Chemin à surveiler
          False,                              // Ne pas surveiller les sous-répertoires
          File_NOTIFY_CHANGE_File_NAME        // Surveiller les changements de noms
         +File_NOTIFY_CHANGE_LAST_WRITE);     // et les écritures
        // Mémorisation de l'heure de la demande
        DateHeureVerification:=Now;
        ListeAjouts.Add('<DEBUT:'+CheminEnCours+'>');
      End;

      Synchronize(MiseAJourListe);
    End;

    // Une demande de notification est en cours
    If HandleNotification<>INVALID_HANDLE_VALUE
    Then Begin
      // Il faut donc demander à Windows d'être prévenu en cas de modification
      // La sortie de WaitForSingleObject est effectuée dans le cas d'une notification
      // ou dans le cas d'un TimeOut. Il ne faut pas ici utiliser le timeout INFINITE
      // sinon le thread risque d'être bloqué en permanence.
      Case WaitForSingleObject(HandleNotification,200Of
        WAIT_Object_0:Begin
            // Dans le cas d'une notification il faut rechercher
            // les fichiers modifiés depuis le dernier appel
            ListeAjouts.Clear;
            If FindFirst(CheminEnCours+PathDelim+'*.*',faAnyFile,Infos)=0
            Then Begin
              Repeat
                // Le fichier à été modifié, on l'ajoute à la liste
                If FileDateToDateTime(Infos.Time)>DateHeureVerification
                Then Begin
                  // FindData.CFileName n'est utilisable que sous Windows
                  ListeAjouts.Add(FormatDateTime('DD/MM/YYYY HH:NN:SS'
                     ,FileDateToDateTime(Infos.Time))+'='+StrPas(Infos.FindData.cFileName));
                End;
              Until FindNext(Infos)<>0;
              FindClose(Infos);

              // Ajout des fichiers modifiés dans le Memo
              // Comme c'est un Thread, il n'est pas possible de modifier directement Memo1
              Synchronize(MiseAJourListe);
            End;
            // Mémorisation de l'heure en cours pour le prochain test
            DateHeureVerification:=Now;
          End;
        WAIT_TIMEOUT :;
      End;

      // Le handle doit être mis à jour pour pouvoir effectuer une nouvelle demande
      FindNextChangeNotification(HandleNotification);
    End;
  End;

  // Libération du Handle en cas de besoin
  If HandleNotification<>INVALID_HANDLE_VALUE 
    Then FindCloseChangeNotification(HandleNotification);
  HandleNotification:=INVALID_HANDLE_VALUE;

  // Libération des objets
  ListeAjouts.Free;
End;

// Cette procédure ne doit être appelée que par l'intermédiaire de Synchronize
Procedure TThreadSurveillance.MiseAJOurListe;
Begin
  Form1.Memo1.Lines.AddStrings(ListeAjouts);
End;

// Création du Thread
Procedure TForm1.FormCreate(Sender: TObject);
Begin
  ThreadSurveillance:=TThreadSurveillance.Create(False);
End;

// Libération du Thread
Procedure TForm1.FormClose(Sender: TObject; Var Action: TCloseAction);
Begin
  If ThreadSurveillance<>Nil
  Then Begin
    ThreadSurveillance.Terminate;
    ThreadSurveillance.WaitFor;
  End;
End;

Procedure TForm1.Button1Click(Sender: TObject);
Begin
  CheminASurveiller:=Edit1.Text;
End;

End.

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2003 Bruno Guérangé. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.