CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

公布原代码:几个很有用的类

楼主fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)2006-06-14 02:44:43 在 VC/MFC / 基础类 提问

一、快捷方式文件的解析类  
   
  快捷方式的文件实际上是*.lnk文件,在命令行里可以看到,下面这个类提供了方便的解析lnk文件的目标的方法。  
   
   
  ///////////////////////////////////////////////////////////////////////  
  //   lnkparser.h  
  //   Creamdog  
   
  #pragma   once  
   
  EXTERN_C   const   CLSID   CLSID_ShellLink;  
   
  #ifdef   UNICODE  
  #define   IID_IShellLink     IID_IShellLinkW  
  #else  
  #define   IID_IShellLink     IID_IShellLinkA  
  #endif   //   !UNICODE  
   
   
  class   CLnkParser  
  {  
  public: //   公有函数  
  CLnkParser(   void   ); //   构造函数  
  ~CLnkParser(   void   ); //   析构函数  
  HRESULT   LoadFile(   LPCWSTR   lpFileName   );  
  HRESULT   GetTargetPath(   LPTSTR   lpStr,   int   cch   );  
  private: //   私有函数  
  HRESULT   Initialize(   void   ); //   数据初始化  
  void   Uninitialize(   void   ); //   数据释放  
  private: //   私有成员  
  IShellLink   *m_pShellLink; //   IShellLink接口指针  
  IPersistFile   *m_pPersistFile; //   IPersistFile接口指针  
  };  
   
   
   
  ///////////////////////////////////////////////////////////////////////  
  //   lnkparser.cpp  
  //   Creamdog  
  #include   "lnkparser.h"  
   
   
  //   构造函数  
  CLnkParser::CLnkParser(   void   )  
  :   m_pShellLink(   NULL   ),   m_pPersistFile(   NULL   )  
  {  
  //   初始化成员数据  
  HRESULT   hr   =   S_OK;  
  lb_init:  
  hr   =   Initialize();  
  if   (   hr   ==   CO_E_NOTINITIALIZED   )  
  {  
  hr   =   CoInitialize(   NULL   );  
  if   (   SUCCEEDED(   hr   )   )  
  {  
  goto   lb_init;  
  }  
  }  
  if   (   FAILED(   hr   )   )  
  {  
  //   如果失败,释放数据  
  Uninitialize();  
  //   掷出异常  
  throw   (   _T("Initialize   failed.")   );  
  }  
  }  
   
  //   析构函数  
  CLnkParser::~CLnkParser(   void   )  
  {  
  //   释放数据  
  Uninitialize();  
  }  
   
  //   读取文件  
  HRESULT   CLnkParser::LoadFile(   LPCWSTR   lpFileName   )  
  {  
  HRESULT   hr   =   S_OK; //   返回值  
  //   以只读方式加载指定的文件数据  
  hr   =   m_pPersistFile->Load(   lpFileName,   STGM_READ   );  
  //   如果失败,返回错误  
  if   (   FAILED(hr)   )  
  {  
  return   hr;  
  }  
  //   解析文件,接受消息的父窗体置零  
  hr   =   m_pShellLink->Resolve(   NULL,   SLR_ANY_MATCH   );  
  //   如果失败,返回错误  
  if   (   FAILED(hr)   )  
  {  
  return   hr;  
  }  
  return   S_OK;  
  }  
   
  HRESULT   CLnkParser::GetTargetPath(   LPTSTR   lpStr,   int   cch   )  
  {  
  HRESULT   hr   =   S_OK;  
  hr   =   m_pShellLink->GetPath(   lpStr,   cch,   NULL,   SLGP_RAWPATH   );  
  if   (   FAILED(hr)   )  
  {  
  return   hr;  
  }  
  return   S_OK;  
  }  
   
  //   成员数据初始化  
  HRESULT   CLnkParser::Initialize(   void   )  
  {  
  HRESULT   hr   =   S_OK; //   返回值  
  //   创建IShellLink接口实例  
  hr   =   CoCreateInstance(   CLSID_ShellLink,   NULL,   CLSCTX_INPROC_SERVER,  
  IID_IShellLink,   (LPVOID*)&m_pShellLink   );  
  //   如果创建失败,输出错误信息,结束程序  
  if   (   FAILED(hr)   )  
  {  
  return   hr;  
  }  
   
  //   从IShellLink接口查询创建IPersistFile接口实例  
  hr   =   m_pShellLink->QueryInterface(   IID_IPersistFile,   (LPVOID*)&m_pPersistFile   );  
  //   如果创建失败,输出错误信息,结束程序  
  if   (   FAILED(hr)   )  
  {  
  return   hr;  
  }  
  return   S_OK;  
  }  
   
  //   释放成员数据  
  void   CLnkParser::Uninitialize(   void   )  
  {  
  //   释放m_pPersistFile接口,指针置零  
  if   (   m_pPersistFile   )  
  {  
  m_pPersistFile->Release();  
  m_pPersistFile   =   NULL;  
  }  
  //   释放m_pShellLink接口,指针置零  
  if   (   m_pShellLink   )  
  {  
  m_pShellLink->Release();  
  m_pShellLink   =   NULL;  
  }  
  }  
   
   
  用法:  
  先包含必要的头文件,缺什么加什么就行了。  
  CLnkParser   LnkParser;  
  LnkParser.LoadFile(   L"lnk文件名"   );  
  TCHAR   szTarget[MAX_PATH];  
  LnkParser.GetTargetPath(   szTarget,   MAX_PATH   );   //   获得目标路径  
   
  问题点数:0、回复次数:54Top

1 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-14 02:53:43 得分 0

二、查找文件类  
  比起MFC的那个CFileFind更轻巧,灵活  
   
   
  ///////////////////////////////////////////////////////////////////////  
  //   findfile.h  
  //   Creamdog  
   
  #pragma   once  
   
  #define   FINDFILE_CONTINUE   0 //   继续查找  
  #define   FINDFILE_ABORT   1 //   终止查找  
  #define   FINDFILE_BREAK   2 //   跳出当前子目录  
  #define   FINDFILE_SKIP   3 //   跳过当前文件  
   
  //   查找通知回调函数  
  typedef   DWORD   (WINAPI   *LPFINDFILE_NOTIFY_ROUTINE)(  
    DWORD_PTR   dwParam,   LPWIN32_FIND_DATA   lpFindData,   LPCTSTR   lpPath   );  
   
  class   CFindFile  
  {  
  public:  
  //   构造  
  CFindFile(   void   );  
  //   查找  
  BOOL   Find(   LPCTSTR   lpRootPath,   LPFINDFILE_NOTIFY_ROUTINE   lpFindRoutine,  
  DWORD_PTR   dwParam,   BOOL   bRecursionFind   =   TRUE,  
  LPCTSTR   lpWildcard   =   NULL   );  
  private:  
  void   ResetWildcard(   void   );  
  BOOL   FindProc(   LPCTSTR   lpRootPath   );  
  DWORD   FindNotify(   const   LPWIN32_FIND_DATA   lpFindData,   LPCTSTR   lpPath   );  
  private:  
  TCHAR   m_szWildcard[MAX_PATH];  
  DWORD   m_dwWildcardLen;  
  DWORD_PTR   m_dwParam;  
  BOOL   m_bRecursionFind;  
  LPFINDFILE_NOTIFY_ROUTINE   m_lpFindRoutine;  
  };  
   
  ///////////////////////////////////////////////////////////////////////  
  //   findfile.cpp  
  //   Creamdog  
  #include   "findfile.h"  
   
  CFindFile::CFindFile(   void   )  
  {  
  m_bRecursionFind   =   TRUE;  
  m_lpFindRoutine   =   NULL;  
  m_dwParam   =   0;  
  ResetWildcard();  
  }  
   
  void   CFindFile::ResetWildcard(   void   )  
  {  
  m_szWildcard[0]   =   _T('*');  
  m_szWildcard[1]   =   _T('\0');  
  m_dwWildcardLen   =   1;  
  }  
   
  //   lpRootPath:查找的根目录  
  //   lpFindRoutine:回调函数地址  
  //   dwParam:传递给回调函数的参数  
  //   bRecursionFind:是否递归查找子目录  
  //   lpWildcard:通配符  
  BOOL   CFindFile::Find(   LPCTSTR   lpRootPath,  
    LPFINDFILE_NOTIFY_ROUTINE   lpFindRoutine,  
    DWORD_PTR   dwParam,   BOOL   bRecursionFind,  
    LPCTSTR   lpWildcard   )  
  {  
  if   (   NULL   ==   lpRootPath   ||   NULL   ==   lpFindRoutine   )  
  {  
  SetLastError(   ERROR_INVALID_PARAMETER   );  
  return   FALSE;  
  }  
  //   重置通配符  
  ResetWildcard();  
  //   如果指定了通配符  
  if   (   lpWildcard   !=   0   )  
  {  
  //   测算通配符长度  
  m_dwWildcardLen   =   (DWORD)lstrlen(   lpWildcard   );  
  //   如果长度超标则返回错误  
  if   (   m_dwWildcardLen   >=   MAX_PATH   )  
  {  
  m_dwWildcardLen   =   1;  
  SetLastError(   ERROR_INVALID_PARAMETER   );  
  return   FALSE;  
  }  
  //   复制通配符到成员  
  lstrcpyn(   m_szWildcard,   lpWildcard,   MAX_PATH   );  
  }  
  m_dwParam   =   dwParam;  
  m_bRecursionFind   =   bRecursionFind;  
  m_lpFindRoutine   =   lpFindRoutine;  
  return   FindProc(   lpRootPath   );  
  }  
   
  DWORD   CFindFile::FindNotify(   LPWIN32_FIND_DATA   lpFindData,   LPCTSTR   lpPath   )  
  {  
  //   检查是否找到的是路径引导  
  LPCTSTR   lpName   =   lpFindData->cFileName;  
  return   m_lpFindRoutine(   m_dwParam,   lpFindData,   lpPath   );  
  }  
   
  BOOL   CFindFile::FindProc(   LPCTSTR   lpRootPath   )  
  {  
  TCHAR   szFullName[MAX_PATH];  
  WIN32_FIND_DATA   stFindData;  
  //   获得根目录添加通配符后的字符串长度  
  DWORD   dwFullNameLen   =   lstrlen(   lpRootPath   )   +   m_dwWildcardLen   +   1;  
   
  if   (   dwFullNameLen   >=   MAX_PATH   )  
  {  
  SetLastError(   ERROR_FILE_NOT_FOUND   );  
  return   FALSE;  
  }  
  //   为目录增加通配符  
  lstrcpyn(   szFullName,   lpRootPath,   MAX_PATH   );  
  lstrcat(   szFullName,   _T("\\")   );  
  lstrcat(   szFullName,   m_szWildcard   );  
   
  //   开始查找第一个文件,出错则退出  
  HANDLE   hFindFile   =   FindFirstFile(   szFullName,   &stFindData   );  
  if   (   hFindFile   ==   INVALID_HANDLE_VALUE   )  
  {  
  return   ERROR_ACCESS_DENIED   ==   GetLastError();  
  }  
   
  BOOL   bReturn   =   TRUE;  
  //   准备FullName;  
  lstrcpyn(   szFullName,   lpRootPath,   MAX_PATH   );  
  lstrcat(   szFullName,   _T("\\")   );  
  dwFullNameLen   =   lstrlen(   szFullName   );  
  //   开始循环查找文件  
  while   (   TRUE   )  
  {  
  //   调用通知  
  DWORD   dwResult   =   FindNotify(   &stFindData,   lpRootPath   );  
  if   (   FINDFILE_ABORT   ==   dwResult   )  
  {  
  bReturn   =   FALSE;  
  SetLastError(   ERROR_OPERATION_ABORTED   );  
  break;  
  }  
  if   (   FINDFILE_BREAK   ==   dwResult   )  
  {  
  break;  
  }  
  //   如果找到的是路径,并且允许递归,用户也没有跳过,则查找子文件夹  
  if   (   stFindData.cFileName[0]   !=   _T('.')   &&  
  (stFindData.dwFileAttributes   &   FILE_ATTRIBUTE_DIRECTORY)   &&  
  m_bRecursionFind   &&   FINDFILE_SKIP   !=   dwResult   )  
  {  
  lstrcpy(   &szFullName[0]   +   dwFullNameLen,   stFindData.cFileName   );  
   
  //   递归调用查找  
  if   (   FALSE   ==   FindProc(   szFullName   )   )  
  {  
  //   如果出错继续返回错误  
  bReturn   =   FALSE;  
  break;  
  }  
  }  
   
  //   如果找不到更多的文件  
  if   (   FALSE   ==   FindNextFile(   hFindFile,   &stFindData   )   )  
  {  
  //   判断是否出错  
  if   (   GetLastError()   !=   ERROR_NO_MORE_FILES   )  
  {  
  bReturn   =   FALSE;    
  }  
  //   跳出循环  
  break;  
  }  
  }  
   
  //   关闭查找文件句柄  
  FindClose(   hFindFile   );  
   
  //   返回错误码  
  return   bReturn;  
  }  
   
   
   
  用法  
  实现一个类似于下面的函数  
   
   
  DWORD   WINAPI   FindFileNotify(   DWORD_PTR   dwParam,  
    LPWIN32_FIND_DATA   lpFindData,   LPCTSTR   lpPath   )  
  {  
          cout   <<   lpPath   <<   "\\"   <<   lpFindData->cFileName;  
          return   FINDFILE_CONTINUE;  
  }  
   
  查找文件:  
  CFindFile   FindFile;  
  FindFile.Find(   _T("c:"),   FindFileNotify,   0   );Top

2 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-14 02:56:16 得分 0

三、计时器类  
   
  这个计时器很久以前写的了,性能不错,直接以double类型返回计时的秒数,很方便  
   
   
  class   CTimer  
  {  
  public:  
  __forceinline   CTimer(   void   )  
  {  
  QueryPerformanceFrequency(   &m_Frequency   );  
  QueryPerformanceCounter(   &m_StartCount   );  
  }  
  __forceinline   void   Reset(   void   )  
  {  
  QueryPerformanceCounter(   &m_StartCount   );  
  }  
  __forceinline   double   End(   void   )  
  {  
  static   __int64   nCurCount;  
  QueryPerformanceCounter(   (PLARGE_INTEGER)&nCurCount   );  
  return   double(   nCurCount   -   (   *(__int64*)&m_StartCount   )   )   /   double(   *(__int64*)&m_Frequency   );  
  }  
  private:  
  LARGE_INTEGER   m_Frequency;  
  LARGE_INTEGER   m_StartCount;  
  };  
   
   
  用法:  
  CTimer   tt;  
  执行你的代码  
  cout   <<   "共用时"   <<   tt.end()   <<   "秒"   <<   endl;  
  tt.Reset();  
  执行你的代码  
  cout   <<   "共用时"   <<   tt.end()   <<   "秒"   <<   endl;  
  Top

3 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-14 02:59:27 得分 0

四:开机时清除“最近的文档”文件夹  
   
  这不是一个类,直接建一个win32工程,把上面的findfile加放工程,再把下面的代码粘到主程序文件中就可以了  
   
   
  int   APIENTRY   WinMain(   HINSTANCE   hInstance,   HINSTANCE   hPrevInstance,   LPSTR   lpCmdLine,   int   nCmdShow   )  
  {  
  HKEY   hFolderKey   =   NULL;  
  TCHAR   szPath[MAX_PATH];  
  DWORD   dwBufLen   =   sizeof(szPath);  
  LONG   lReturn   =   RegOpenKeyEx(   HKEY_CURRENT_USER,  
  _T("Software\\Microsoft\\Windows\\")  
  _T("CurrentVersion\\Explorer\\Shell   Folders"),  
  0,   KEY_READ,&   hFolderKey   );  
  if   (   lReturn   !=   ERROR_SUCCESS   )  
  {  
  return   -1;  
  }  
  lReturn   =   RegQueryValueEx(   hFolderKey,   _T("Recent"),   NULL,  
  NULL,   (LPBYTE)szPath,   &dwBufLen   );  
  if   (   lReturn   !=   ERROR_SUCCESS   )  
  {  
  return   -1;  
  }  
  if   (   lReturn   !=   RegCloseKey(   hFolderKey   )   )  
  {  
  return   -1;  
  }  
  CFindFile   ff;  
  if   (   FALSE   ==   ff.Find(   szPath,   FindFileNotify,   0,   FALSE   )   )  
  {  
  return   -1;  
  }  
  return   0;  
  }  
  Top

4 楼gudulyn(冰楠)回复于 2006-06-14 07:45:26 得分 0

markTop

5 楼NJHS(天上来客(中国程序先锋网www.cppn.net)大量免费源代码下载)回复于 2006-06-14 08:14:04 得分 0

好  
  收藏Top

6 楼honker110(honker)回复于 2006-06-14 08:44:56 得分 0

不错,谢谢了  
  我来转一个,不用MFC和FindFirst()查找文件的例子  
   
  #include   <string>  
  #include   <vector>  
  #include   <map>  
  #include   <iostream>  
  #include   <fstream>  
   
  #include   <io.h>  
   
  main(){  
  std::string   str   =   "<html><head><title>ISAPI   Upload   Demo</title></head><body>";  
  struct   _finddata_t   c_file;            
                  long   hFile;            
   
  /*       Find       first       .c       file       in       current       directory       */            
  if((hFile   =   _findfirst("*.*",   &c_file))   ==   -1L)            
  printf("No   files   in   directory!\n");            
  else            
  {            
  str   +=   c_file.name;  
  str   +=   "<br>";  
  /*       Find       the       rest       of       the       .c       files       */            
  while(       _findnext(       hFile,       &c_file       )       ==       0       )            
  {  
  str   +=   c_file.name;  
  str   +=   "<br>";  
  }            
   
  _findclose(       hFile       );            
  }            
   
  str   +=   "</body></html>";  
   
  printf(str.c_str());  
  }Top

7 楼winks(少爷)回复于 2006-06-16 08:24:04 得分 0

markTop

8 楼zblaoshu1979(周博)回复于 2006-06-16 08:36:12 得分 0

很好,收藏Top

9 楼liushaoyi0704(【化外之民】)回复于 2006-06-16 08:53:38 得分 0

收藏Top

10 楼brookqdc(小溪)回复于 2006-06-16 09:23:37 得分 0

markTop

11 楼Soft_micro()回复于 2006-06-16 09:31:55 得分 0

路过Top

12 楼whwjn(哈哈)回复于 2006-06-16 16:01:13 得分 0

amrkTop

13 楼femalelover(楼主, 请把用不着的可用分捐给我1/3 :()回复于 2006-06-17 11:12:55 得分 0

嗯,多搞搞这种,大家这样交流应该能有进步.Top

14 楼yimain(我活过,所以无怨无悔.)回复于 2006-06-17 11:17:11 得分 0

好东西,收藏了.  
  多谢!Top

15 楼Tian_Dao_Akane(小西--楼主请不要给我分,谢谢!)回复于 2006-06-17 14:35:08 得分 0

果然是有用的东东,谢谢楼主了!Top

16 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-17 15:16:45 得分 0

继续放,监控注册表和文件夹改动的类  
   
   
  /////////////////////////////////////////////////////////////////////////////  
  //changenotify.h  
   
   
  #pragma   once  
   
  #define   ERROR_NOTIFY 100000L  
  #define   ERROR_NOTIFY_ALREADY_START (   ERROR_NOTIFY   +   1   )  
   
  ///////////////////////////////////////////////////////////////////////////////  
   
  DWORD   CALLBACK   ChangeMonitorThread(   LPVOID   pParam   );  
  class   CChangeMonitor  
  {  
  public:  
  CChangeMonitor();  
  virtual   ~CChangeMonitor();  
  virtual   BOOL   StartMoniter(   DWORD   dwMonId,   HWND   hWnd   );  
  virtual   void   EndMoniter(   void   );  
  virtual   void   Pause(   void   );  
  virtual   void   Resume(   void   );  
  protected:  
  virtual   void   SendNotify(   UINT   nMsg   );  
  virtual   void   CallNextMoniter(   void   )   =   0;  
  virtual   DWORD   WaitNotify(   void   )   =   0;  
  protected:  
  DWORD   m_dwMonId;  
  HANDLE   m_hThread;  
  HWND   m_hWnd;  
  DWORD   m_dwThreadId;  
   
  friend   DWORD   CALLBACK   ChangeMonitorThread(   LPVOID   pParam   );  
  };  
   
   
  ///////////////////////////////////////////////////////////////////////////////  
   
  class   CDirectoryMonitor   :   public   CChangeMonitor  
  {  
  public:  
  CDirectoryMonitor();  
  ~CDirectoryMonitor();  
  BOOL   StartMoniter(   DWORD   dwMonId,   HWND   hWnd,   LPCTSTR   lpPath,  
  BOOL   bSubTree   =   TRUE,   DWORD   dwFilter   =   FILE_NOTIFY_CHANGE_LAST_WRITE   );  
  void   EndMoniter(   void   );  
  protected:  
  virtual   void   CallNextMoniter(   void   );  
  virtual   DWORD   WaitNotify(   void   );  
  protected:  
  HANDLE   m_hNotify;  
  };  
   
  ///////////////////////////////////////////////////////////////////////////////  
   
  class   CRegistryMonitor   :   public   CChangeMonitor  
  {  
  public:  
  CRegistryMonitor();  
  ~CRegistryMonitor();  
  BOOL   StartMoniter(   DWORD   dwMonId,   HWND   hWnd,   HKEY   hRoot,   LPCTSTR   lpSubKey,  
  DWORD   dwFilter   =   REG_NOTIFY_CHANGE_NAME   |   REG_NOTIFY_CHANGE_LAST_SET   );  
  void   EndMoniter(   void   );  
  protected:  
  virtual   void   CallNextMoniter(   void   );  
  virtual   DWORD   WaitNotify(   void   );  
  protected:  
  HANDLE   m_hNotify;  
  HKEY   m_hKey;  
  DWORD   m_dwFilter;  
  };  
   
   
   
   
   
  /////////////////////////////////////////////////////////////////////////////  
  //changenotify.cpp  
   
   
   
   
   
  #include   "ChangeNotify.h"  
   
   
  CChangeMonitor::CChangeMonitor(   void   )  
  :   m_hThread(   NULL   )  
  ,   m_hWnd(   NULL   )  
  ,   m_dwThreadId(   0   )  
  ,   m_dwMonId(   0   )  
  {  
  }  
   
  CChangeMonitor::~CChangeMonitor(   void   )  
  {  
  EndMoniter();  
  }  
   
  BOOL   CChangeMonitor::StartMoniter(   DWORD   dwMonId,   HWND   hWnd   )  
  {  
  //   判断是否已经启动监视  
  if   (   NULL   !=   m_hThread   )  
  {  
  SetLastError(   ERROR_NOTIFY_ALREADY_START   );  
  TRACE_ERROR(   GetLastError()   );  
  return   FALSE;  
  }  
  //   检查参数  
  if   (   NULL   ==   hWnd   )  
  {  
  SetLastError(   ERROR_INVALID_PARAMETER   );  
  TRACE_ERROR(   GetLastError()   );  
  return   FALSE;  
  }  
  m_dwMonId   =   dwMonId;  
  m_hWnd   =   hWnd;  
  //   创建监视线程  
  m_hThread   =   CreateThread(   NULL,   0,   ChangeMonitorThread,  
  (LPVOID)this,   CREATE_SUSPENDED,   &m_dwThreadId   );  
  ASSERT(   NULL   !=   m_hThread   );  
  return   TRUE;  
  }  
   
  void   CChangeMonitor::EndMoniter(   void   )  
  {  
  //   判断线程是否存在  
  if   (   m_hThread   )  
  {  
  //   判断线程是否结束  
  DWORD   dwExitCode;  
  VERIFY(   GetExitCodeThread(   m_hThread,   &dwExitCode   )   );  
  if   (   STILL_ACTIVE   ==   dwExitCode   )  
  {  
  ASSERT(   m_dwThreadId   !=   0   );  
  //   向线程发送退出消息  
  VERIFY(   PostThreadMessage(   m_dwThreadId,   WM_MONITER_EXIT,   0,   0   )   );  
  //   使线程继续,以便结束  
  Resume();  
  //   等待线程退出  
  DWORD   dwWaitResult   =   WaitForSingleObject(   m_hThread,   INFINITE   );  
  ASSERT(   WAIT_FAILED   !=   dwWaitResult   );  
  //   如果等待超时,强制结束线程  
  if   (   WAIT_TIMEOUT   ==   dwWaitResult   )  
  {  
  if   (   FALSE   ==   TerminateThread(   m_hThread,   0   )   )  
  {  
  TRACE_ERROR(   -1   );  
  }  
  }  
  }  
  //   关闭线程句柄,将线程相关数据置零  
  VERIFY(   CloseHandle(   m_hThread   )   );  
  m_hThread   =   NULL;  
  m_dwThreadId   =   0;  
  }  
  m_hWnd   =   NULL; //   通知窗体置零  
  }  
   
  void   CChangeMonitor::Pause(   void   )  
  {  
  ASSERT(   m_hThread   );  
  SuspendThread(   m_hThread   );  
  }  
   
  void   CChangeMonitor::Resume(   void   )  
  {  
  ASSERT(   m_hThread   );  
  ResumeThread(   m_hThread   );  
  }  
   
  void   CChangeMonitor::SendNotify(   UINT   nMsg   )  
  {  
  //   检查通知窗体句柄是否存在  
  ASSERT(   m_hWnd   !=   NULL   );  
  //   发送通知消息  
  if   (   FALSE   ==   PostMessage(   m_hWnd,   nMsg,   m_dwMonId,   0   )   )  
  {  
  TRACE_ERROR(   GetLastError()   );  
  }  
  }  
   
  DWORD   CALLBACK   ChangeMonitorThread(   LPVOID   pParam   )  
  {  
  //   检查参数是否为空  
  ASSERT(   pParam   !=   NULL   );  
  //   得到监视器类对象指针  
  CChangeMonitor   *pChaMon   =   (CChangeMonitor*)pParam;  
  //   检查对象  
  ASSERT(   pChaMon->m_hThread   !=   NULL   );  
  ASSERT(   pChaMon->m_hWnd   !=   NULL   );  
  ASSERT(   pChaMon->m_dwThreadId   !=   0   );  
  //   进入线程消息循环  
  MSG   msg; //   消息数据结构  
  while(   FALSE   ==   PeekMessage(   &msg,   NULL,   WM_MONITER_EXIT,  
  WM_MONITER_EXIT,   PM_REMOVE   )   )  
  {  
  //   以0超时等待通知,直接返回等待结果  
  DWORD   dwWaitResult   =   pChaMon->WaitNotify();  
  ASSERT(   dwWaitResult   !=   WAIT_FAILED   );  
  switch(   dwWaitResult   ) //   处理等待结果  
  {  
  case   WAIT_OBJECT_0: //   通知已接收  
  //   向接收者发送通知消息  
  pChaMon->SendNotify(   WM_MONITER_CHANGED   );  
  //   继续下一次等待  
  pChaMon->CallNextMoniter();  
  break;  
  case   WAIT_TIMEOUT:  
  break;  
  }  
  Sleep(   50   );  
  }  
  return   0;  
  }  
   
   
  ///////////////////////////////////////////////////////////////////////////////  
  //   CDirectoryMonitor  
   
  //   构造函数  
  CDirectoryMonitor::CDirectoryMonitor(   void   )  
  :   m_hNotify(   NULL   )  
  {  
  }  
   
  //   析构函数  
  CDirectoryMonitor::~CDirectoryMonitor(   void   )  
  {  
  }  
   
  //   启动监视  
  BOOL   CDirectoryMonitor::StartMoniter(   DWORD   dwMonId,   HWND   hWnd,   LPCTSTR   lpPath,  
    BOOL   bSubTree,   DWORD   dwFilter   )  
  {  
  //   调用父类同名函数  
  if   (   FALSE   ==   CChangeMonitor::StartMoniter(   dwMonId,   hWnd   )   )  
  {  
  return   FALSE;  
  }  
  //   创建监视  
  m_hNotify   =   FindFirstChangeNotification(   lpPath,   bSubTree,   dwFilter   );  
  if   (   INVALID_HANDLE_VALUE   ==   m_hNotify   )  
  {  
  m_hNotify   =   NULL;  
  EndMoniter();  
  TRACE_ERROR(   GetLastError()   );  
  return   FALSE;  
  }  
  //   启动监视线程  
  VERIFY(   ResumeThread(   m_hThread   )   );  
  return   TRUE;  
  }  
   
  void   CDirectoryMonitor::EndMoniter(   void   )  
  {  
  //   调用父类同名函数  
  CChangeMonitor::EndMoniter();  
  //   判断通知句柄是否存在  
  if   (   m_hNotify   )  
  {  
  //   结束通知  
  VERIFY(   FindCloseChangeNotification(   m_hNotify   )   );  
  m_hNotify   =   NULL; //   通知句柄置零  
  }  
  }  
   
  void   CDirectoryMonitor::CallNextMoniter(   void   )  
  {  
  VERIFY(   TRUE   ==   FindNextChangeNotification(   m_hNotify   )   );  
  }  
   
  DWORD   CDirectoryMonitor::WaitNotify(   void   )  
  {  
  return   WaitForSingleObject(   m_hNotify,   0   );  
  }  
   
   
   
  ///////////////////////////////////////////////////////////////////////////////  
  //   CRegistryMonitor  
   
  //   构造函数  
  CRegistryMonitor::CRegistryMonitor(   void   )  
  :   m_hKey(   NULL   )  
  ,   m_hNotify(   NULL   )  
  ,   m_dwFilter(   0   )  
  {  
  }  
   
  //   析构函数  
  CRegistryMonitor::~CRegistryMonitor(   void   )  
  {  
  }  
   
  //   启动监视  
  BOOL   CRegistryMonitor::StartMoniter(   DWORD   dwMonId,   HWND   hWnd,   HKEY   hRoot,  
  LPCTSTR   lpSubKey,   DWORD   dwFilter   )  
  {  
  //   调用父类同名函数  
  if   (   FALSE   ==   CChangeMonitor::StartMoniter(   dwMonId,   hWnd   )   )  
  {  
  return   FALSE;  
  }  
  //   成员数据赋值  
  m_dwFilter   =   dwFilter;  
  //   打开注册表键  
  LONG   lr;  
  lr   =   RegOpenKeyEx(   hRoot,   lpSubKey,   0,   KEY_NOTIFY,   &m_hKey   );  
  if   (   ERROR_SUCCESS   !=   lr   )  
  {  
  TRACE_ERROR(   lr   );  
  return   FALSE;  
  }  
  //   创建通知事件句柄  
  m_hNotify   =   CreateEvent(   NULL,   FALSE,   FALSE,   NULL   );  
  ASSERT(   NULL   !=   m_hNotify   );  
  //   开始监视  
  CallNextMoniter();  
  //   启动监视线程  
  VERIFY(   ResumeThread(   m_hThread   )   );  
  return   TRUE;  
  }  
   
  //   结束监视  
  void   CRegistryMonitor::EndMoniter(   void   )  
  {  
  CChangeMonitor::EndMoniter();  
  if   (   m_hNotify   )  
  {  
  VERIFY(   CloseHandle(   m_hNotify   )   );  
  m_hNotify   =   NULL;  
  }  
  if   (   m_hKey   )  
  {  
  VERIFY(   ERROR_SUCCESS   ==   RegCloseKey(   m_hKey   )   );  
  m_hKey   =   NULL;  
  }  
  }  
   
  void   CRegistryMonitor::CallNextMoniter(   void   )  
  {  
  ASSERT(   m_hKey   !=   NULL   );  
  ASSERT(   m_hNotify   !=   NULL   );  
  //   创建监视句柄  
  VERIFY(   ERROR_SUCCESS   ==   RegNotifyChangeKeyValue(   m_hKey,   TRUE,  
  m_dwFilter,   m_hNotify,   TRUE   )   );  
  }  
   
  DWORD   CRegistryMonitor::WaitNotify(   void   )  
  {  
  return   WaitForSingleObject(   m_hNotify,   0   );  
  }  
   
   
  Top

17 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-17 15:22:47 得分 0

少了三个define,加到头文件里就行了  
   
  #define   WM_MONITER (   WM_USER   +   1000   )  
  #define   WM_MONITER_EXIT (   WM_MONITER   +   1   )  
  #define   WM_MONITER_CHANGED (   WM_MONITER   +   2   )  
   
   
  忘了说用法了  
   
  CDirectoryMonitor是用来监控文件夹  
  CRegistryMonitor用来监控注册表键  
   
  以CDirectoryMonitor为例  
   
  CDirectoryMonitor   DirNotify;  
  DirNotify.StartMoniter(   给一个ID,   用来接收消息的窗体句柄,你要监控的文件夹   );  
   
  在窗体里响应WM_MONITER_CHANGED事件,当WM_MONITER_CHANGED发送,就代表文件夹被改动了Top

18 楼xialin168(林)回复于 2006-06-17 18:31:42 得分 0

收藏Top

19 楼chenyulin(chen)回复于 2006-06-17 18:40:52 得分 0

支持,收藏Top

20 楼qiqi_007(不要理我)回复于 2006-06-17 19:10:30 得分 0

mark  
   
  ==================================  
  = CSDN助手 全面支持CSDN论坛  
  = 监视、收藏、历史、签名走马灯  
  ==================================Top

21 楼2shcm(尝尝微笑)回复于 2006-07-19 21:17:38 得分 0

支持,收藏Top

22 楼lk919(修改你在CSDN社区的信息)回复于 2006-07-19 21:35:21 得分 0

mark一下Top

23 楼FigoZhu(谢慕安)回复于 2006-07-19 21:37:15 得分 0

markTop

24 楼cime63(流浪的孩子)回复于 2006-07-19 22:03:47 得分 0

markTop

25 楼kencharles(肯.查尔斯)回复于 2006-07-19 22:14:21 得分 0

MarkTop

26 楼teli_eurydice(哭泣的仙人掌。。。。)回复于 2006-07-19 22:36:50 得分 0

markTop

27 楼seu07201213(【_】〖汪洋中的一片叶子〗≈^︵^≈)回复于 2006-07-19 22:41:52 得分 0

收了Top

28 楼pomelowu(羽战士)回复于 2006-07-19 23:01:18 得分 0

发现我还没markTop

29 楼dzq138(钟添)回复于 2006-07-19 23:59:31 得分 0

收藏啦..楼主.多谢你...Top

30 楼openforever(++)回复于 2006-07-20 08:14:27 得分 0

MARKTop

31 楼laiyiling(陌生人[MVP])回复于 2006-07-20 08:22:09 得分 0

zcTop

32 楼yjukh(小虫)回复于 2006-07-20 08:42:38 得分 0

收藏Top

33 楼PLYAT(山野的風)回复于 2006-07-20 08:44:56 得分 0

谢谢楼主!Top

34 楼lfchen(一条晚起的虫--床上用品[家纺]专卖)回复于 2006-07-20 08:44:59 得分 0

markTop

35 楼nayc(不是牛太老,而是草太嫩)回复于 2006-07-20 08:48:58 得分 0

收藏~Top

36 楼AIRFLYNET(汪洋中的一条船)回复于 2006-07-20 08:49:25 得分 0

收Top

37 楼Nowish(看我能忍耐多久)回复于 2006-07-20 09:02:20 得分 0

Mark~Top

38 楼Scarroot(每天一贴,把分用完.)回复于 2006-07-20 09:11:04 得分 0

markTop

39 楼leizeal(在路上)回复于 2006-07-20 09:14:25 得分 0

收藏Top

40 楼angel_rabbit(zj_rabbit)回复于 2006-07-20 09:15:46 得分 0

mark...Top

41 楼zorro0799(猪状元)回复于 2006-07-20 09:17:12 得分 0

占位Top

42 楼universee(吾乃太极语言之父)回复于 2006-07-20 09:32:12 得分 0

markTop

43 楼whwjn(哈哈)回复于 2006-07-20 09:35:36 得分 0

mmmTop

44 楼seekg()回复于 2006-07-20 09:45:24 得分 0

机Top

45 楼rageliu(天气好了就去长白山看水怪去了,嘿嘿...)回复于 2006-07-20 09:51:15 得分 0

3Q!!!!!!!!Top

46 楼ypine(青松)回复于 2006-07-20 09:53:48 得分 0

markTop

47 楼wubaowang(Knowledge is power)回复于 2006-07-20 09:55:51 得分 0

收藏...Top

48 楼flyskytoday(夜漫漫路漫漫)回复于 2006-07-20 10:32:19 得分 0

收藏   谢谢Top

49 楼booklove(纳海行云)回复于 2006-07-20 10:41:13 得分 0

mkTop

50 楼ziaikongqi(liujun)回复于 2006-07-20 11:12:57 得分 0

MARK!Top

51 楼guyanhun(老婆说的都是对的!努力做个好老公!)回复于 2006-07-20 12:27:11 得分 0

学习   !  
  Top

52 楼960379(文物:眉毛搭桥)回复于 2006-07-20 13:24:56 得分 0

收藏!谢谢楼主Top

53 楼broccoli(-_-||)回复于 2006-07-21 15:11:41 得分 0

markTop

54 楼striking(庸人自扰)回复于 2006-07-21 15:19:21 得分 0

收藏!谢谢楼主Top

相关问题

关键词

得分解答快速导航

  • 帖主:fireseed

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

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