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.
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 WhileNot Terminated Do Begin // Le chemin demandé à changé => On change la surveillance If CheminASurveiller<>CheminEnCours ThenBegin
ListeAjouts.Clear;
// Une demande est en cours, on libère le Handle If HandleNotification<>INVALID_HANDLE_VALUE ThenBegin
FindCloseChangeNotification(HandleNotification);
HandleNotification:=INVALID_HANDLE_VALUE;
ListeAjouts.Add('<FIN>'); End;
// Prise en compte de la nouvelle demande
CheminEnCours:=CheminASurveiller; If CheminEnCours<>'' ThenBegin // 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 ThenBegin // 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 ThenBegin Repeat // Le fichier à été modifié, on l'ajoute à la liste If FileDateToDateTime(Infos.Time)>DateHeureVerification ThenBegin // 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 ThenBegin
ThreadSurveillance.Terminate;
ThreadSurveillance.WaitFor; End; End;
Procedure TForm1.Button1Click(Sender: TObject); Begin
CheminASurveiller:=Edit1.Text; End;