?
Solved

Better monitoring of change notification handles

Posted on 1998-09-01
6
Medium Priority
?
180 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

741 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