CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

如何用c++builder编程实现时实监视哪些文件被访问过?

楼主Adayuer(饭碗饭碗饭碗你在哪里?)2001-05-23 10:23:00 在 C++ Builder / 基础类 提问

请高手帮忙   ,最好能带说明原理的例程,谢谢!!! 问题点数:20、回复次数:10Top

1 楼luhongjun(过江项羽)回复于 2001-05-23 10:58:00 得分 5

看一看  
  http://community.borland.com/article/0,1410,21743,00.html  
   
  你不会失望的。Top

2 楼rh(花覆茅檐)回复于 2001-05-23 11:31:00 得分 0

英文啊!Top

3 楼rh(花覆茅檐)回复于 2001-05-23 11:32:00 得分 15

The   concept   behind   directory   monitoring   is   fairly   simple.   As   I   said   above,   this   can   be   done   using   the   function   FindFirstChangeNotification.   That   said   and   done,   how   do   we   go   about   actually   using   the   thing?   First   lets   look   at   the   prototype,   as   given   by   Microsoft:  
   
  HANDLE   FindFirstChangeNotification(  
      LPCTSTR   lpPathName,         //   directory   name  
      BOOL   bWatchSubtree,         //   monitoring   option  
      DWORD   dwNotifyFilter       //   filter   conditions  
  );  
     
   
   
   
   
  Parameters  
    lpPathName:   the   path   of   the   directory   to   monitor  
    bWatchSubtree:   whether   or   not   to   recursively   monitor   subdirectories  
    dwNotifyFilter:   flags   to   control   monitoring   conditions  
   
  The   options   available   for   dwNotifyFilter   are   as   follows:  
   
   
    Value   Meaning    
  FILE_NOTIFY_CHANGE_FILE_NAME   Any   file   name   change   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.   Changes   include   renaming,   creating,   or   deleting   a   file   name.    
  FILE_NOTIFY_CHANGE_DIR_NAME   Any   directory-name   change   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.   Changes   include   creating   or   deleting   a   directory.    
  FILE_NOTIFY_CHANGE_ATTRIBUTES   Any   attribute   change   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.    
  FILE_NOTIFY_CHANGE_SIZE   Any   file-size   change   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.   The   operating   system   detects   a   change   in   file   size   only   when   the   file   is   written   to   the   disk.   For   operating   systems   that   use   extensive   caching,   detection   occurs   only   when   the   cache   is   sufficiently   flushed.    
  FILE_NOTIFY_CHANGE_LAST_WRITE   Any   change   to   the   last   write-time   of   files   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.   The   operating   system   detects   a   change   to   the   last   write-time   only   when   the   file   is   written   to   the   disk.   For   operating   systems   that   use   extensive   caching,   detection   occurs   only   when   the   cache   is   sufficiently   flushed.    
  FILE_NOTIFY_CHANGE_SECURITY   Any   security-descriptor   change   in   the   watched   directory   or   subtree   causes   a   change   notification   wait   operation   to   return.    
   
   
   
   
  The   return   value   of   this   function   is   a   windows   HANDLE   type.   It   gives   us   a   Windows   event   object,   which   is   an   object   that   can   be   set   to   have   a   signalled   state.   Using   this   event   handle,   we   can   call   the   WaitForSingleObject   or   WaitForMultipleObjects   functions   to   wait   until   it   is   signalled   (the   monitored   directory   has   changed   in   some   way).   Once   the   event   becomes   signalled   (i.e.   a   change   was   detected),   it   is   necessary   to   call   the   FindNextChangeNotification.   function   to   reset   it.   When   you   are   finished,   you   must   free   the   object   with   FindCloseChangeNotification  
   
  One   way   to   utilize   this   function   in   a   component   is   to   put   it   within   a   thread   with   a   loop   that   calls   FindFirstChangeNotification,   WaitForSingleObject,   FindNextChangeNotification,   and   FindCloseChangeNotification.   Every   time   the   event   object   becomes   signalled,   we   can   call   a   function   in   the   ListBox   component   that   will   notify   it   of   change.  
   
     
  Implementation      
   
   
  In   implementing   a   directory   monitoring   and   auto-updating   file   ListBox,   there   are   a   couple   of   things   to   keep   in   mind:   how   to   monitor   the   directory   without   locking   your   application,   and   how   to   notify   the   control.One   relatively   simple   way   of   accomplishing   this   is   to   create   a   thread   that   monitors   the   directory   and   calls   back   to   the   ListBox   component   when   there   is   a   change.   In   the   following   source,   both   code   for   a   ListBox   and   for   the   monitoring   thread   are   provided.  
   
  Here   is   the   code   for   the   component:  
   
  ActiveListBox.h    
  //---------------------------------------------------------------------------  
   
  #ifndef   ActiveListBoxH  
  #define   ActiveListBoxH  
  //---------------------------------------------------------------------------  
  #include   <SysUtils.hpp>  
  #include   <Controls.hpp>  
  #include   <Classes.hpp>  
  #include   <Forms.hpp>  
  #include   <StdCtrls.hpp>  
  //---------------------------------------------------------------------------  
   
  //Here   we   combine   the   flags   into   one   easy-to-use   dword  
  const   unsigned   long   dwFlags   =   FILE_NOTIFY_CHANGE_FILE_NAME|  
                                                          FILE_NOTIFY_CHANGE_DIR_NAME|  
                                                          FILE_NOTIFY_CHANGE_ATTRIBUTES|  
                                                          FILE_NOTIFY_CHANGE_SIZE|  
                                                          FILE_NOTIFY_CHANGE_LAST_WRITE;  
  class   TActiveListBox;  
   
  class   TDirectoryThread   :   public   TThread  
  {  
  private:  
      HANDLE   hNotify;         //Event   object   handle  
      TActiveListBox   *control;         //ListBox   back   pointer   (to   notify   it)  
      String   path;         //Path   to   monitor  
      void   __fastcall   Update();  
      void   __fastcall   ThreadFinish(TObject   *Sender);  
  protected:  
      void   __fastcall   Execute();  
  public:  
      __fastcall   TDirectoryThread(TActiveListBox   *ctrl);  
      void   __fastcall   SetMonitorPath(String   path);  
  };  
  //---------------------------------------------------------------------------  
  class   PACKAGE   TActiveListBox   :   public   TListBox  
  {  
  private:  
      bool   path_set;  
      TNotifyEvent   FOnChangeFile;         //Change   event  
      TDirectoryThread   *thrd;         //Monitoring   thread  
      AnsiString   FPath;  
      void   __fastcall   SetPath(String   path);  
      void   __fastcall   PopulateFileList();  
  protected:  
  public:  
      __fastcall   TActiveListBox(TComponent*   Owner);  
      __fastcall   ~TActiveListBox();  
      void   __fastcall   UpdateNotify();  
      void   __fastcall   Restart();  
  __published:  
      __property   AnsiString   MonitorPath   =   {read=FPath,write=SetPath};  
      __property   TNotifyEvent   OnDirectoryChange   =   {read=FOnChangeFile,write=FOnChangeFile};  
  };  
  //---------------------------------------------------------------------------  
  #endif  
     
   
  ActiveListBox.cpp    
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "ActiveListBox.h"  
  #pragma   package(smart_init)  
  //---------------------------------------------------------------------------  
  //   ValidCtrCheck   is   used   to   assure   that   the   components   created   do   not   have  
  //   any   pure   virtual   functions.  
  //  
   
  static   inline   void   ValidCtrCheck(TActiveListBox   *)  
  {  
      new   TActiveListBox(NULL);  
  }  
  //---------------------------------------------------------------------------  
  __fastcall   TActiveListBox::TActiveListBox(TComponent*   Owner)  
      :   TListBox(Owner)  
  {  
      path_set=false;                                           //boolean   to   check   if   path   has   been   set  
      FPath="";  
      FOnChangeFile=NULL;  
      thrd   =   new   TDirectoryThread(this);     //create   thread  
  }  
  //---------------------------------------------------------------------------  
  __fastcall   TActiveListBox::~TActiveListBox()  
  {  
      thrd->Terminate();  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TActiveListBox::SetPath(String   path)  
  {  
      FPath   =   path;  
      PopulateFileList();  
      thrd->SetMonitorPath(FPath);  
      if   (!path_set)                                 //if   the   path   hasn't   been   set   yet...  
      {  
          path_set=true;  
          thrd->Resume();                           //start   the   thread  
      }  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TActiveListBox::UpdateNotify()   //notify   the   listbox   of   changes  
  {  
      PopulateFileList();  
      if   (FOnChangeFile)  
          FOnChangeFile(this);  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TActiveListBox::PopulateFileList()   //fill   list   box   w/   files  
  {  
      TSearchRec   sr;  
      Items->Clear();  
      if   (FPath   ==   "")   return;  
      FindFirst(FPath+"*.*",faAnyFile,sr);  
      do   {  
          Items->Add(sr.Name);  
      }   while   (!FindNext(sr));  
      FindClose(sr);  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TActiveListBox::Restart()  
  {  
      path_set=false;  
      thrd   =   new   TDirectoryThread(this);  
  }  
  //---------------------------------------------------------------------------  
  namespace   Activelistbox  
  {  
      void   __fastcall   PACKAGE   Register()  
      {  
            TComponentClass   classes[1]   =   {__classid(TActiveListBox)};  
            RegisterComponents("Samples",   classes,   0);  
      }  
  }  
  //---------------------------------------------------------------------------  
  __fastcall   TDirectoryThread::TDirectoryThread(TActiveListBox   *ctrl)  
      :   TThread(true)  
  {  
      control   =   ctrl;  
      path   =   "";  
      FreeOnTerminate   =   true;  
      OnTerminate   =   ThreadFinish;  
      hNotify   =   INVALID_HANDLE_VALUE;  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TDirectoryThread::Execute()  
  {  
      if   (path.IsEmpty()   ||   (hNotify   ==   INVALID_HANDLE_VALUE))  
      {  
          control->Restart();  
          throw   Exception("couldn't   start");  
      }  
      bool   to=true;     //time-out   check  
      //while   we're   still   going...  
      while   (!Terminated   &&   (hNotify   !=   INVALID_HANDLE_VALUE))  
      {  
          //while   we're   still   timed   out...  
          while   (to   &&   !Suspended   &&   !Terminated)  
          {  
              unsigned   long   stat   =   WaitForSingleObject(hNotify,2000);  
              //our   call   to   WaitForSingleObject   has   a   2   second   timeout   to   avoid   thread-lock  
              if   (stat   ==   WAIT_OBJECT_0)   //if   it   got   signalled  
              {  
                  to=true;  
                  Synchronize(Update());     //update   list   box  
                  //use   Synchronize   to   keep   it   thread-safe  
                  if   (!FindNextChangeNotification(hNotify))   //renew   the   handle  
                  {  
                      to=false;  
                      break;  
                  }  
              }  
              else   if   (stat   ==   WAIT_TIMEOUT)             //just   keep   going  
                  to=true;  
              else   {  
                  to=false;  
                  break;  
              }  
          }  
      }  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TDirectoryThread::SetMonitorPath(String   Path)  
  {  
      if   (path   !=   Path)  
      {  
          path   =   Path;  
          if   (hNotify   !=   INVALID_HANDLE_VALUE)         //close   our   old   handle  
              FindCloseChangeNotification(hNotify);  
   
          hNotify   =   FindFirstChangeNotification(path.c_str(),false,dwFlags);  
          //get   the   handle   to   the   event   object  
          if   (hNotify   ==   INVALID_HANDLE_VALUE)  
              throw   Exception("couldn't   make   handle");  
      }  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TDirectoryThread::ThreadFinish(TObject   *Sender)  
  {  
      FindCloseChangeNotification(hNotify);   //cleanup  
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TDirectoryThread::Update()  
  {  
      control->UpdateNotify();  
  }  
   
     
     
  Top

4 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2001-05-26 09:50:00 得分 0

谢谢Top

5 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2001-05-31 08:33:00 得分 0

Top

6 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2001-05-31 08:33:00 得分 0

Top

7 楼xrbeck(ALEK)回复于 2001-05-31 08:36:00 得分 0

妈呀。。。跑路Top

8 楼TR@SOE()回复于 2001-05-31 09:01:00 得分 0

可以使用控件。Orpheus里的SysTools中封装了一个。Top

9 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2001-05-31 17:25:00 得分 0

在哪能得到这个控件,免费的吗?Top

10 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2001-06-15 20:19:00 得分 0

Top

相关问题

  • 如何用c++builder编程实现时实监视哪些文件文件被访问过?
  • 《C++ Builder 5编程实例与技巧》
  • SQL数据库与C++ Builder编程
  • 有关C++BUILDER的编程的?
  • C++Builder多线程编程实例
  • 如何用C#下的Raw Socket编程实现网络封包监视
  • oracle&unix-c编程
  • 怎样在C++Builder下使用纯粹的win32API编程
  • c++builder编程的一些初级问题
  • 关于Borland C++ Builder 的多层数据库编程的问题

关键词

  • tactivelistbox
  • hnotify
  • tdirectorythread
  • fastcall
  • fonchangefile
  • changes
  • fpath
  • notify
  • activelistbox
  • populatefilelist

得分解答快速导航

  • 帖主:Adayuer
  • luhongjun
  • rh

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo