Article View: borland.public.cppbuilder.nativeapi
Article #8277Re: Monitoring folder changes (FindFirstChangeNotification): Multiple f-ion calls
From: Tom Woodrow
Date: Tue, 09 Nov 2004 15:51
Date: Tue, 09 Nov 2004 15:51
219 lines
6528 bytes
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-mailReferences:
<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