c++ SHChangeNotifyRegister的使用
最近研究怎么检测一个文件的改动,也就是实时读取文件改动信息,看到SHChangeNotifyRegister,觉得这个可行!求大侠们也给怎么使用的意见,和代码参考下!
[解决办法]
#include "stdafx.h"#include "MonitorChanged.h"#include <InitGuid.h>#include <ShlObj.h>#include <ShellAPI.h>#define MAX_LOADSTRING 100#define WM_MONITOR WM_USER+123#define SHCNRF_ShellLevel 0x0002 // 全局变量:HINSTANCE hInst; // 当前实例TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名DWORD dwNotifyID=0;typedef struct{ DWORD dwItem1; DWORD dwItem2; }SHNOTIFYSTRUCT; // 此代码模块中包含的函数的前向声明:ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。 MSG msg; HACCEL hAccelTable; // 初始化全局字符串 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_MONITORCHANGED, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MONITORCHANGED)); // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } SHChangeNotifyDeregister(dwNotifyID); return (int) msg.wParam;}ATOM MyRegisterClass(HINSTANCE hInstance){ WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MONITORCHANGED)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MONITORCHANGED); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex);}BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } IShellFolder *m_lpsfDesktop; SHGetDesktopFolder(&m_lpsfDesktop); LPITEMIDLIST pidl; m_lpsfDesktop->ParseDisplayName(NULL, NULL, _T("H:\\"), NULL, &pidl, NULL); SHChangeNotifyEntry shcne; shcne.pidl=pidl; shcne.fRecursive=TRUE; dwNotifyID=::SHChangeNotifyRegister(hWnd,SHCNRF_ShellLevel, SHCNE_RENAMEITEM|SHCNE_CREATE|SHCNE_DELETE|SHCNE_MKDIR|SHCNE_RMDIR|SHCNE_RENAMEFOLDER, WM_MONITOR,1,&shcne); m_lpsfDesktop->Release(); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_MONITOR: { TCHAR ch[MAX_PATH]={0}; TCHAR ch2[MAX_PATH]={0}; switch(lParam) { case SHCNE_RENAMEITEM: //收到两次消息 ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem2),ch2); OutputDebugStringW(_T("RENAME FILE:\nOLD PATH - ")); OutputDebugStringW(ch); OutputDebugStringW(_T("\nNEW PATH - ")); OutputDebugStringW(ch2); OutputDebugStringW(_T("\n")); break; case SHCNE_CREATE: ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); OutputDebugStringW(_T("CREATE FILE:\nPATH - ")); OutputDebugStringW(ch); break; case SHCNE_DELETE: ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); OutputDebugStringW(_T("DELETE FILE:\nPATH - ")); OutputDebugStringW(ch); break; case SHCNE_MKDIR: ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); OutputDebugStringW(_T("CREATE FOLDER:\nPATH - ")); OutputDebugStringW(ch); break; case SHCNE_RMDIR: ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); OutputDebugStringW(_T("DELETE FOLDER:\nPATH - ")); OutputDebugStringW(ch); break; case SHCNE_RENAMEFOLDER: //收到两次消息 ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem1),ch); ::SHGetPathFromIDList((LPCITEMIDLIST)LongToPtr(((SHNOTIFYSTRUCT*)wParam)->dwItem2),ch2); OutputDebugStringW(_T("RENAME FOLDER:\nOLD PATH - ")); OutputDebugStringW(ch); OutputDebugStringW(_T("\nNEW PATH - ")); OutputDebugStringW(ch2); OutputDebugStringW(_T("\n")); break; } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}// “关于”框的消息处理程序。INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE;}