Solved

Better monitoring of change notification handles

Posted on 1998-09-01
6
177 Views
Last Modified: 2010-08-05
Hello
   I am currently monitoring changes using change notification handles (FindFirstChangeNotification) in a custom control. It works well, but teh control requires focus to update the view. I would like it to be autonomous, in that it will respond privately and immediately to notified handles, perhaps by hooking a windows-issued message (if any) or by having a TEvent object initiate the update (I would prefer this). I currently check the handles manually in some general events (for-loop checking a THandle array with WaitforSingleObject...). I would also like to avoid instantiating a (an addtional!) thread or using a timer (same thing). Is this possible?

Any suggestions?

Regards,
Edo
0
Comment
Question by:Edo082297
  • 3
  • 2
6 Comments
 
LVL 3

Expert Comment

by:Matvey
ID: 1338394
Maybe you search for a message like WM_DeviceChange? A message that will notify you when new files are written and deleted? (I think it's not exactly THE message, I just can't recall the exact one...)
0
 
LVL 5

Expert Comment

by:inter
ID: 1338395
Hi Edo,
The change notification is almost instantly triger a specified object. So, your focusing problem is due to the component design. In my opinion(and also programmed an object for it previously) using a seperate thread object which watches for multiple events are what you need. Here what I have programmed before:-it is a code fragment from my unit-

//*********CODE STARTS
// This one can poll a directory for changes
type
  TDirNotify = class(TThread)
  protected
    FDir : string;   //directory to watch
    FWObj: THandle;  //event handle given by OS
    FOnChange : TNotifyEvent;
    procedure SetDir(D : String);
    procedure Execute;override;
  public
    constructor Create(ADir : string);
    destructor Destroy;override;
    property Directory : string read FDir write SetDir;
    property OnChange : TNotifyEvent read FOnChange write FOnChange;
  end;

implementation


{$R *.DFM}

// ****************************************************************
// TDirNotify
// ****************************************************************

procedure TDirNotify.SetDir(D : String);
begin
  if D <> FDir then
  begin
    FDir := D;
    if FWObj <> 0 then
       FindCloseChangeNotification(FWObj);
    FWObj := FindFirstChangeNotification(PChar(FDir), false,
                                             FILE_NOTIFY_CHANGE_FILE_NAME //or
//                                             FILE_NOTIFY_CHANGE_DIR_NAME or
//                                             FILE_NOTIFY_CHANGE_ATTRIBUTES or
//                                             FILE_NOTIFY_CHANGE_SIZE or
//                                             FILE_NOTIFY_CHANGE_LAST_WRITE or
//                                             FILE_NOTIFY_CHANGE_SECURITY
                                               );
    if FWObj = INVALID_HANDLE_VALUE then
       raise Exception.Create('TDirNotify.SetDir : Can not hook a directory notification filter');
  end;
end;

procedure TDirNotify.Execute;
begin
  while not Terminated do
  begin
    if WaitForSingleObject(FWObj, 1000) = WAIT_OBJECT_0 then
    begin
      try //catch exceptions due to the user
        if Assigned(FOnChange) then FOnChange(Self);
      except
      end;
      FindNextChangeNotification(FWObj);
    end;
    Sleep(10);
  end;
end;

constructor TDirNotify.Create(ADir : string);
begin
  inherited Create(False);
  FWObj:= 0;
  Directory := ADir;
  FreeOnTerminate := true;
end;

destructor TDirNotify.Destroy;
begin
  if FWObj <> 0 then
     FindCloseChangeNotification(FWObj);
  inherited Destroy;
end;
//*********CODE ENDS

You can change the object you watch at create, above i only check for rename operations. It is not a component so you have to create an instance of it by yourself.
First create it and assign OnChange event to it.
Regards, Igor
0
 
LVL 1

Author Comment

by:Edo082297
ID: 1338396
Hi Igor

I have no problem with what you are suggesting, but Delphi documentation recommends no more than 16 threads in the same session. I currently add a notification handle whenever the user is in a particular directory, so I could potentially end up with a lot of threads. Isn't this a problem? I would almost prefer to use a timer and check all the handles in one shot, rather than instantiate a separate thread for each one. But I don't like the timer solution because it lacks sophistication(!). Then again, perhaps it is the best solution. What do you think?

Regards,
Edo


0
ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 
LVL 5

Expert Comment

by:inter
ID: 1338397
Hi
we can solve it with single thread and by using waitformultipleobject instead for wait for single object. Then we change the type of OnChange as follows
  TOnChangeEvent = procedure (const DirName);
By this way, when we detect change notification we call the onchange with the coresponding directory name.
This should pose additional coding such adding AddNotification(dirname:string) and holding all the dirs and coresponding notification event handles in that class -may be in stringlist- (By now I have no time to implement this but may be tomorrow I can...or any other friend-may be you- can do it without much effort)
Regards, Igor
0
 
LVL 1

Author Comment

by:Edo082297
ID: 1338398
Hi Igor
  I already do exactly that, so yes, I will implement it that way. Post an answer, I will award you the points if you like.

Regards,
Edo
0
 
LVL 5

Accepted Solution

by:
inter earned 50 total points
ID: 1338399
Thanks friend,
just call if you need cooperation
Regards, Igor
0

Featured Post

Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Simple Delphi Question 9 90
Making delphi communicate with a c# service 16 103
drawing animated level bar based on numbers 3 97
Installshield for Embarcadero EX 10.1 Berlin 4 41
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question