🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: Monitoring folder changes (FindFirstChangeNotification): Multiple f-ion calls

#8277
From: Tom Woodrow
Date: Tue, 09 Nov 2004 15:51
219 lines
6528 bytes
There is a component in the Disk Controls component package from 
AppControls that does this in the background.

Tom Woodrow

Vladimir Stefanovic wrote:

> Hi,
> 
> I found a class (BCB Journal, april 2001) that monitors for
> folder changes, but I cannot control it as I want. I want it
> to react only when some file in folder (not subfolders) is:
> 
> (1) created
> (2) changed
> (3) deleted
> 
> ie, flags = FILE_NOTIFY_CHANGE_FILE_NAME |
>    FILE_NOTIFY_CHANGE_LAST_WRITE;
> 
> But the problem is, that the function MyAction() is
> executed 2 or 4 times for file creation, and 2 times for
> file change. Only when the file is deleted, the function
> is executed once - as I wanted.
> 
> Is this normal?
> 
> --- code that prepares for notification ---
> 
>    TChangeNotification *note;
> 
>    __fastcall TForm1::TForm1(TComponent* Owner)
>            : TForm(Owner)
>    {
>       note = new TChangeNotification ( this );
>       note->Folder =  "C:\\Test";
>       note->WatchSubFolders = false;
>       note->OnChange = MyAction;
>       note->Start();
>    }
> 
>    __fastcall TForm1::~TForm1()
>    {
>       note->Stop();
>       delete note;
>    }
> 
>    void __fastcall TForm1::MyAction(TObject* Sender)
>    {
>       Memo1->Lines->Add( "Changed!" );
>    }
> 
> I tried to include the flags (see below) but, the result is
> not changed. I also tried to wait a while and ProcessMessages
> in a loop but the result was still the same.
> 
>    bool InProgress = false;
> 
>    void __fastcall TForm1::MyAction(TObject* Sender)
>    {
>       if ( InProgress )
>          return;
>       try
>       {
>          InProgress = true;
>          Memo1->Lines->Add( "Changed!" );
>       }
>       __finally
>       {
>          InProgress = false;
>       }
>    }
> 
> The Start() & Stop() which are public for the class, if I use
> in MyAction(), instead of InProgress, stucks the app. I think
> that's because the Stop() doesn't make any checks, just deletes
> the thread (see the class).
> 
> I feel that I have to modify the class, but what part? Or I should
> try to use Borland's solution I saw once somewhere in borland
> develpoers network.
> 
> --- class ---
> 
> DWORD dir_ch_not_flags = FILE_NOTIFY_CHANGE_FILE_NAME |
>                          FILE_NOTIFY_CHANGE_LAST_WRITE;
> 
> __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 );
> }
> 
> 
> --
> 
> 
> Best regards,
> Vladimir Stefanovic
> 
> 
> 
Technical Details
Message-ID: <4190e795$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!feeder.enertel.nl!nntpfeed-01.ops.asmr-01.energis-idc.net!216.196.110.149.MISMATCH!border2.nntp.ams.giganews.com!nntp.giganews.com!news-hub.cableinet.net!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <4190e2a3@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,1dc9679112d7194f
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
Date: Tue, 09 Nov 2004 07:51:50 -0800
From: Tom Woodrow <tomwoodrow@comcast.net>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax)
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Re: Monitoring folder changes (FindFirstChangeNotification): Multiple
 f-ion calls
References: <4190e2a3@newsgroups.borland.com>
In-Reply-To: <4190e2a3@newsgroups.borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 24.6.92.22
Message-ID: <4190e795$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1100015509 24.6.92.22 (9 Nov 2004 07:51:49 -0700)
Lines: 219
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!feeder.enertel.nl!nntpfeed-01.ops.asmr-01.energis-idc.net!216.196.110.149.MISMATCH!border2.nntp.ams.giganews.com!nntp.giganews.com!news-hub.cableinet.net!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail