?
Solved

Better monitoring of change notification handles

Posted on 1998-09-01
6
Medium Priority
?
182 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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 150 total points
ID: 1338399
Thanks friend,
just call if you need cooperation
Regards, Igor
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses
Course of the Month15 days, 4 hours left to enroll

840 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