The subject for this month is utility which may be used to monitor a folder or directory written in Visual C++ version 6.0 Foundation Classes. This is a multithreading dialog based MFC application which uses a 'Worker Thread' to monitor any Directory or Folder for changes. It then displays a directory listing containing the file date, size and name. The display is sorted according to file time. The program is very efficient because it uses Microsoft Windows System API functions to monitor the subject directory. In particular it uses the 'Change Notification' mechanism along with multithread WaitForMultipleObjects() functions. It responds to various folder changes including:
Because there is no periodic polling or scaning of the directory, the program uses virtually no CPU power inspite of the fact that it's response to changes is instantaneous. So fast, in fact, that a 2 second timer had to be added to allow the user to read a fast moving display.
///////////////////////////////////////////////////////////////////////////// // Multi thread addons... MONITOR ALL DIRECTORY CHANGES HERE UINT CWDlg::WorkerThread(PVOID pParam) // Controlling function (Must be static.) { HANDLE hChange; DWORD result, more=1; HANDLE hArray[2]; CWDlg *mDlg = (CWDlg *) pParam; // // add to message map, OnInitDialog(), etc. // // hKillMonitor = CreateEvent(NULL, FALSE, FALSE, NULL); // pWThread = AfxBeginThread(WorkerThread, this); // #define WM_MYUPDATEWINDOW (WM_APP + 1) // ON_MESSAGE(WM_MYUPDATEWINDOW, OnMyUpdateWindow) // long OnMyUpdateWindow(UINT wParam, LPARAM lParam) hChange = FindFirstChangeNotification(mDlg->gPath, false, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SECURITY); hArray[0] = hChange; hArray[1] = mDlg->hKillMonitor; if (INVALID_HANDLE_VALUE != hChange) { while(more) { result = WaitForMultipleObjects(2, hArray, false, INFINITE); switch (result-WAIT_OBJECT_0) { case 0: mDlg->PostMessage(WM_MYUPDATEWINDOW,TRUE); FindNextChangeNotification(hChange); break; case 1: more = 0; // kill monitor event was asserted or 'set' break; } } FindCloseChangeNotification(hChange); } return 0; }