🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #1216

Re: To know when a file is modified

#1216
From: Vladimir Stefanovic
Date: Tue, 09 Oct 2007 11:48
285 lines
7511 bytes
--- DirChNot.h ---
#ifndef DirChNotH
#define DirChNotH

#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>

class PACKAGE TChangeNotification : public TComponent
   {
   __published:
      __property TNotifyEvent OnChange = {read = onChange, write = 
SetOnChange};
      __property TNotifyEvent OnError = {read = onError, write = 
SetOnError};
      __property bool WatchSubFolders = {read = watchSubFolders, write = 
SetWatchSubFolders};
      __property String Folder = {read = folder, write = folder};

   public:
      __fastcall TChangeNotification(TComponent *owner);
      __fastcall ~TChangeNotification();

      void __fastcall Start();
      void __fastcall Stop();

   private:
      void __fastcall SetOnChange(TNotifyEvent event);
      void __fastcall SetOnError(TNotifyEvent event);
      void __fastcall SetWatchSubFolders(bool watch);
      void __fastcall SetFolder(String aFolder);

      TNotifyEvent onChange;
      TNotifyEvent onError;
      bool watchSubFolders;
      String folder;

      class TCNThread : public TThread
         {
         friend TChangeNotification;

         public:
            __fastcall TCNThread(TChangeNotification *owner);
            __fastcall ~TCNThread();

            void __fastcall Execute();
            void __fastcall Notify(void);
            void __fastcall Error(void);

         private:
            TChangeNotification *owner;
            HANDLE handle;
         } *thread;
   };

#endif   // ChangeNotificationH


--- DirChNot.cpp ---
#include <vcl.h>
#pragma hdrstop

#include "DirChNot.h"

DWORD dir_ch_not_flags = FILE_NOTIFY_CHANGE_FILE_NAME |
                         FILE_NOTIFY_CHANGE_LAST_WRITE;


// FILE_NOTIFY_CHANGE_FILE_NAME
// Any filename change in the watched directory or subtree causes a change
// notification wait operation to return. Changes include renaming, 
creating,
// or deleting a filename.

// FILE_NOTIFY_CHANGE_DIR_NAME
// Any directory-name change in the watched directory or subtree causes a
// change notification wait operation to return. Changes include creating or
// deleting a directory.

// FILE_NOTIFY_CHANGE_ATTRIBUTES
// Any attribute change in the watched directory or subtree causes a change
// notification wait operation to return.

// FILE_NOTIFY_CHANGE_SIZE
// Any file-size change in the watched directory or subtree causes a change
// notification wait operation to return. The operating system detects a 
change
// in file size only when the file is written to the disk. For operating
// systems that use extensive caching, detection occurs only when the cache 
is
// sufficiently flushed.

// FILE_NOTIFY_CHANGE_LAST_WRITE
// Any change to the last write-time of files in the watched directory or
// subtree causes a change notification wait operation to return. The 
operating
// system detects a change to the last write-time only when the file is 
written
// to the disk. For operating systems that use extensive caching, detection
// occurs only when the cache is sufficiently flushed.

// FILE_NOTIFY_CHANGE_SECURITY
// Any security-descriptor change in the watched directory or subtree causes 
a
// change notification wait operation to return.

__fastcall TChangeNotification::TChangeNotification(TComponent *owner) : 
TComponent(owner)
{
   onChange = 0;
   onError = 0;
   thread = 0;
   watchSubFolders = False;
}

__fastcall TChangeNotification::~TChangeNotification()
{
   delete thread;
}

void __fastcall TChangeNotification::Start()
{
   if ( thread == 0 )
      thread = new TCNThread(this);
}

void __fastcall TChangeNotification::Stop()
{
   delete thread;
   thread = 0;
}

void __fastcall TChangeNotification::SetFolder(String aFolder)
{
   if ( thread != 0 )
   {
      Stop();
      folder = aFolder;
      Start();
   }
   else
      folder = aFolder;
}

void __fastcall TChangeNotification::SetOnChange(TNotifyEvent event)
{
   if ( thread != 0 )
   {
      thread->Suspend();
      onChange = event;
      thread->Resume();
   }
   else
      onChange = event;
}

void __fastcall TChangeNotification::SetOnError(TNotifyEvent event)
{
   if ( thread != 0 )
   {
      thread->Suspend();
      onError = event;
      thread->Resume();
   }
   else
      onError = event;
}

void __fastcall TChangeNotification::SetWatchSubFolders(bool watch)
{
   if ( thread != 0 )
   {
      Stop();
      watchSubFolders = watch;
      Start();
   }
   else
      watchSubFolders = watch;
}

__fastcall TChangeNotification::TCNThread::TCNThread(TChangeNotification 
*owner) : TThread(false), owner(owner)
{
   handle = 0;
}

__fastcall TChangeNotification::TCNThread::~TCNThread()
{
   Terminate();

   if ( handle != 0 )
   {
      FindCloseChangeNotification( handle );
      handle = 0;
   }
}

void __fastcall TChangeNotification::TCNThread::Execute()
{
   handle = FindFirstChangeNotification( owner->Folder.c_str(), 
owner->WatchSubFolders, dir_ch_not_flags );

   if ( handle == INVALID_HANDLE_VALUE )
   {
      Synchronize( Error );
      Terminate();
   }

   while ( !Terminated )
   {
      DWORD status = WaitForSingleObject( handle, INFINITE );

      if ( status == WAIT_OBJECT_0 && Terminated == false )
      {
         Synchronize( Notify );

         if ( FindNextChangeNotification( handle ) == 0 )
         {
            Synchronize( Error );
            Terminate();
         }
      }
      else
      {
         Terminate();
      }
   }
}

void __fastcall TChangeNotification::TCNThread::Notify(void)
{
   if ( owner->OnChange ) owner->OnChange( owner );
}

void __fastcall TChangeNotification::TCNThread::Error(void)
{
   if ( owner->OnError ) owner->OnError( owner );
}

static inline void ValidCtrCheck(TChangeNotification *)
{
   new TChangeNotification( NULL );
}

#pragma package(smart_init)

--- MAIN.CPP ---
// ...
#include "DirChNot.h"
// ...
TChangeNotification *note; // or in class header
// ...
CONSTRUCTOR()
{
   // ...
   note = new TChangeNotification ( this );
   note->Folder =  CONFIG_PATH;
   note->WatchSubFolders = false;
   note->OnChange = YourCode;
   // ...
}
DESTRUCTOR()
{
   // ...
   note->Stop();
   delete note;
   // ...
}
void __fastcall TYourForm::YourCode(TObject* Sender)
{
   // Your Code Here ...
}

--- MAIN.H ---
// ...
   private:
   void __fastcall YourCode(TObject* Sender);
// ...



-- 
Best Regards,
Vladimir Stefanovic
Technical Details
Message-ID: <470b697f$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
References: <470b1068@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,db03f0a10c4cfc4d
X-Google-Attributes: gid10cc67,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Vladimir Stefanovic" <antivari@sbb.co.yu>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <470b1068@newsgroups.borland.com>
Subject: Re: To know when a file is modified
Date: Tue, 9 Oct 2007 13:48:19 +0200
Lines: 287
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2670
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2670
X-RFC2646: Format=Flowed; Response
NNTP-Posting-Host: 195.252.72.241
Message-ID: <470b697f$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1191930239 195.252.72.241 (9 Oct 2007 04:43:59 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail