 |
|
 |
|
 |
17 - SURVEILLANCE D'UN REPERTOIRE
|
|
|
|
PRÉSENTATION :
Programme d'exemple de l'utilisation des notifications de modification de Windows.
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,200) Of
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 oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©
2003 Bruno Guérangé. Aucune reproduction,
même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.
|