利用未公开函数实现Shell操作监视

转载http://topic.csdn.net/t/20061215/11/5232851.html

参考Using the shell to receive notification of removable media being inserted or removed.

http://www.codeproject.com/KB/shell/shchangenotifyregister.aspx?fid=13570&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=346901&fr=26

 

利用未公开函数实现Shell操作监视  
   
  在Windows下有一个未公开函数SHChangeNotifyRegister可以把窗口添加到系统的系统消息监视链中,该函数定义如下:  
   
  function   SHChangeNotifyRegister(hWnd,   uFlags,   dwEventID,   uMSG,   cItems:   LongWord;  
                    lpps:PIDLSTRUCT):   integer;   stdcall;   external   'Shell32.dll'   index   2;  
  //   参数hWnd定义了监视系统操作的窗口得句柄  
  //   参数uFlags、dwEventID定义监视操作参数  
  //   参数uMsg定义操作消息  
  //   参数cItems定义附加参数  
  //   参数lpps指定一个PIDLSTRUCT结构,该结构指定监视的目录  
   
  当函数调用成功之后,函数会返回一个监视操作句柄,同时系统就会将hWnd指定的窗口加入到操作监视链中,当有文件操作发生时,系统会向hWnd发送uMsg指定的消息,我们只要在程序中加入该消息的处理函数就可以实现对系统操作的监视了。如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。  
   
  运行程序,点击打开监视按钮,如果出现一个显示“Shell监视程序成功注册”的对话框,说明Form1已经加入到系统操作监视链中了,可以试着在资源管理器中建立、删除文件夹,移动文件等操作,可以发现这些操作都被纪录下来并显示在文本框中。  
   
  在程序中多次使用到了一个PItemIDList的结构,这个数据结构指定Windows下得一个“项目”,在Windows下资源实现统一管理一个“项目”可以是一个文件或者一个文件夹,也可以是一个打印机等资源。  
   
   
  //   .h  
  //---------------------------------------------------------------------------  
   
  #ifndef   mainH  
  #define   mainH  
  //---------------------------------------------------------------------------  
  #include   <Classes.hpp>  
  #include   <Controls.hpp>  
  #include   <StdCtrls.hpp>  
  #include   <Forms.hpp>  
   
  #define     WM_SHNOTIFY                         0x401  
  //---------------------------------------------------------------------------  
   
  class   TFormMain   :   public   TForm  
  {  
  __published: //   IDE-managed   Components  
          TMemo   *Memo1;  
          void   __fastcall   FormCreate(TObject   *Sender);  
          void   __fastcall   FormClose(TObject   *Sender,   TCloseAction   &Action);  
  private: //   User   declarations  
          void   __fastcall   WMShellReg(TMessage   &   Message);  
   
  BEGIN_MESSAGE_MAP  
          VCL_MESSAGE_HANDLER(WM_SHNOTIFY,   TMessage,   WMShellReg)  
  END_MESSAGE_MAP(TForm)  
   
  public: //   User   declarations  
          __fastcall   TFormMain(TComponent*   Owner);  
  };  
  //---------------------------------------------------------------------------  
  extern   PACKAGE   TFormMain   *FormMain;  
  //---------------------------------------------------------------------------  
  #endif  
   
  //.cpp  
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "main.h"  
  #include   <shlobj.h>  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
   
  TFormMain   *FormMain;  
   
  HWND   m_hSHNotify;  
  LPITEMIDLIST   m_pidlDesktop;  
  //---------------------------------------------------------------------------  
   
  typedef   struct  
  {  
          PItemIDList   dwItem1;  
          PItemIDList   dwItem2;  
  }SHNOTIFYSTRUCT,   *PSHNOTIFYSTRUCT;  
   
  typedef   struct  
  {  
          PItemIDList   pidl;  
          int   bWatchSubFolders;  
  }_IDLSTRUCT,IDLSTRUCT,*PIDLSTRUCT;  
   
  typedef   HWND   (*SHNRegister)(HWND   hWnd,DWORD   uFlags,DWORD   dwEventID,DWORD   uMSG,DWORD   cItems,PIDLSTRUCT   lpps);  
  typedef   HWND   (*SHNUnRegister)(HWND   hNotify);  
   
  SHNRegister   SHChangeNotifyRegister;  
  SHNUnRegister   SHChangeNotifyDeregister;  
   
  String   __fastcall   SHEventName(String   strPath1,   String   strPath2,   DWORD   lParam)  
  {  
          switch(lParam)  
          {  
                  case   SHCNE_RENAMEITEM:         return   "重命名文件"   +   strPath1   +   "为"   +   strPath2;  
                  case   SHCNE_CREATE:                 return   "建立文件:"   +   strPath1;  
                  case   SHCNE_DELETE:                 return   "删除文件:"   +   strPath1;  
                  case   SHCNE_MKDIR:                   return   "新建目录:"   +   strPath1;  
                  case   SHCNE_RMDIR:                   return   "删除目录:"   +   strPath1;  
                  case   SHCNE_MEDIAINSERTED:   return   strPath1   +   "中插入可移动存储介质";  
                  case   SHCNE_MEDIAREMOVED:     return   strPath1   +   "中移去可移动存储介质"   +   strPath1   +   "   "   +   strPath2;  
                  case   SHCNE_DRIVEREMOVED:     return   "移去驱动器"   +   strPath1;  
                  case   SHCNE_DRIVEADD:             return   "添加驱动器"   +   strPath1;  
                  case   SHCNE_NETSHARE:             return   "设置目录"   +   strPath1   +   "为共享";  
                  case   SHCNE_NETUNSHARE:         return   "取消目录"   +   strPath1   +   "的共享";  
                  case   SHCNE_ATTRIBUTES:         return   "改变"   +   strPath1   +   "的属性";  
                  case   SHCNE_UPDATEDIR:           return   "更新目录"   +   strPath1;  
                  case   SHCNE_UPDATEITEM:         return   "更新文件"   +   strPath1;  
                  case   SHCNE_SERVERDISCONNECT:   return   "断开与服务器的连接"   +   strPath1   +   "   "   +   strPath2;  
                  case   SHCNE_UPDATEIMAGE:       return   "执行:SHCNE_UPDATEIMAGE   操作";  
                  case   SHCNE_DRIVEADDGUI:       return   "执行:SHCNE_DRIVEADDGUI   操作";  
                  case   SHCNE_RENAMEFOLDER:     return   "重命名文件夹"   +   strPath1   +   "为"   +   strPath2;  
                  case   SHCNE_FREESPACE:           return   "磁盘空间大小改变";  
                  case   SHCNE_ASSOCCHANGED:     return   "改变文件关联";  
                  case   SHCNE_EXTENDED_EVENT:return   strPath2   +   "目录有变化";  
                  default:   return   "未知操作"   +   IntToStr(lParam);  
          }  
  }  
  //---------------------------------------------------------------------------  
   
  bool   SHNotify_Register(HWND   hWnd)  
  {  
          IDLSTRUCT   ps;  
          if   (m_hSHNotify   ==   0)  
          {  
                  if   (SHGetSpecialFolderLocation(0,   CSIDL_DESKTOP,   &m_pidlDesktop)   ==   NOERROR)  
                  {  
                          if   (m_pidlDesktop)  
                          {  
                                  ps.pidl   =   m_pidlDesktop;  
                                  ps.bWatchSubFolders   =   1;  
                                  m_hSHNotify   =   SHChangeNotifyRegister(hWnd,   SHCNF_TYPE   |   SHCNF_IDLIST,  
                                                  SHCNE_ALLEVENTS   |   SHCNE_INTERRUPT,   WM_SHNOTIFY,   1,   &ps);  
                                  return   (m_hSHNotify   !=   0);  
                          }  
                          else  
                          {  
                                  CoTaskMemFree(m_pidlDesktop);  
                          }  
                  }  
          }  
          return   False;  
  }  
  //---------------------------------------------------------------------------  
   
  bool   SHNotify_UnRegister()  
  {  
          if   (m_hSHNotify   !=   0)  
          {  
                  if(SHChangeNotifyDeregister   ==   NULL)   return   False;  
   
                  if(SHChangeNotifyDeregister(m_hSHNotify))  
                  {  
                          m_hSHNotify   =   0;  
                          CoTaskMemFree(m_pidlDesktop);  
                          return   True;  
                  }  
          }  
          return   False;  
  }  
  //---------------------------------------------------------------------------  
   
  __fastcall   TFormMain::TFormMain(TComponent*   Owner)  
                  :   TForm(Owner)  
  {  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TFormMain::WMShellReg(TMessage   &   Message)  
  {  
          String   strPath1;  
          String   strPath2;  
          char   strPath[256];  
          String   sTmp;  
          PSHNOTIFYSTRUCT   pidlItem;  
   
          pidlItem   =   (PSHNOTIFYSTRUCT)Message.WParam;  
   
          SHGetPathFromIDList(pidlItem->dwItem1,strPath);  
          strPath1   =   strPath;  
          SHGetPathFromIDList(pidlItem->dwItem2,strPath);  
          strPath2   =   strPath;  
   
          sTmp   =   FormatDateTime("[yyyy-mm-dd   hh:mm:ss]:",Now())   +   SHEventName(strPath1,strPath2,Message.LParam);  
   
          Memo1->Lines->Add(sTmp);  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TFormMain::FormCreate(TObject   *Sender)  
  {  
          m_hSHNotify   =   NULL;  
          HMODULE   DLLHandle   =   LoadLibrary("SHELL32.DLL");  
          if(DLLHandle)  
          {  
                  SHChangeNotifyRegister       =   (SHNRegister)GetProcAddress(DLLHandle,(LPCSTR)2);  
                  SHChangeNotifyDeregister   =   (SHNUnRegister)GetProcAddress(DLLHandle,(LPCSTR)4);  
          }  
          FreeLibrary(DLLHandle);  
                   
          SHNotify_Register(Handle);  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TFormMain::FormClose(TObject   *Sender,   TCloseAction   &Action)  
  {  
          SHNotify_UnRegister();  
  }  
  //---------------------------------------------------------------------------  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值