Article View: borland.public.cppbuilder.nativeapi
Article #8276Monitoring folder changes (FindFirstChangeNotification): Multiple f-ion calls
From: Vladimir Stefanovic
Date: Tue, 09 Nov 2004 15:30
Date: Tue, 09 Nov 2004 15:30
209 lines
5627 bytes
5627 bytes
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:
<4190e2a3@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!newsread.com!newsprint.newsread.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,1dc9679112d7194f,start X-Google-Attributes: gid10cc67,public X-Google-Language: ENGLISH,ASCII-7-bit From: "Vladimir Stefanovic" <spam@not.needed> Newsgroups: borland.public.cppbuilder.nativeapi Subject: Monitoring folder changes (FindFirstChangeNotification): Multiple f-ion calls Date: Tue, 9 Nov 2004 16:30:14 +0100 Lines: 212 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2314.1300 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 NNTP-Posting-Host: 213.137.116.237 Message-ID: <4190e2a3@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1100014243 213.137.116.237 (9 Nov 2004 07:30:43 -0700) Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!newsread.com!newsprint.newsread.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail