[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Better monitoring of change notification handles

Posted on 1998-09-01
6
Medium Priority
?
181 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

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…
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…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

649 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