Visit the Ultimate Toolbox main page for an overview and configuration guide to the Ultimate Toolbox library.
Source code and project files for this sample can be found in the samples\file\FileWatcher directory of the sample projects download.
Overview
The class COXFileWatcher
organizes file change notifications in a number of directories supplied by the user. All notifications are handled by a virtual function, which can be overridden in the derived class. The class can also convert these events to window messages. Examples of notifications are: file creation, file deletion, creation of a new directory, file size change, attribute change etc.
Features
- Easy to use in your application (just create a variable).
- The number of watched directories is limited only by the available memory.
- Directories can be added for watching or removed from the watch list at any time.
- Different types of watch filters can be supplied.
- The control can watch a specified directory or the whole directory tree.
- Different approaches for handling the change notifications are possible (via a virtual function or a Windows message).
- Extra info for each type of change that may occur in the watched directories (only available on Windows NT 4.0 or newer).
- Runs in its own thread, so your application may continue its work.
Usage
There are two approaches in using the COXFileWatcher
class. These depend on how you choose to handle the notifications:
- The first approach is to derive a class from
COXFileWatcher
and override the following function:
virtual BOOL OnNotify(COXFileWatchNotifier fileWatchNotifier)
This function is called when a file change notification is received by the file watch object. The function receives a copy of the received parameters in the form of a COXFileWatchNotifier
object. The return value indicates whether this notification should be ignored (TRUE
) or whether the object may continue handling the event (FALSE
). The last option (FALSE) is necessary if the event is to be translated into a window message.
- The second method involves instantiating a
COXFileWatcher
object and associating the watched directories with a window (EnableWindowNotification()
). This window will then receive the WM_OX_FILE_NOTIFY
message with information about file change notifications. (The WPARAM
contains an index (nItemIndex
) which can be linked to a COXFileWatchNotifier
object (see below) through a call to the function GetFileWatchNotifier()
).
In either the first or second case the easiest way to use the class is to create an instance of the class COXFileWatcher
or of the derived one. Then a directory can be supplied for watching with a call to the following function:
BOOL AddWatch(LPCTSTR pszPath, BOOL bWatchSubtree = FALSE,
DWORD nWatchFilter = OXFileWatchChangeFileName |
OXFileWatchChangeLastWrite);
The FileWatcher sample implements the second approach.
First a COXFileWatcher
object is declared as a member of the class:
#include "OXFileWatcher.h"
class CFileWatcherDlg : public CDialog
{
COXFileWatcher fwWatcher;
public:
...
Next, a message handler is set up to trap notifications that will be sent to the dialog (after a call to EnableWindowNotifications
):
BEGIN_MESSAGE_MAP(CFileWatcherDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_ADD_DIR, OnAddDir)
ON_BN_CLICKED(IDC_REMOVE_DIR, OnRemoveDir)
ON_MESSAGE( WM_OX_FILE_NOTIFY, OnFileNotify )
And then the OnFileNotify
function is added - in this case it extracts information from the object with which to populate the list:
LRESULT CFileWatcherDlg::OnFileNotify(WPARAM wP, LPARAM)
{
CString str;
COXFileWatchNotifier fwnNotifier;
fwnNotifier = fwWatcher.GetFileWatchNotifier( wP);
...
return 0;
}
Now all that's needed is to set up the file watcher with information on the files/directories to be tracked - the sample uses a dialog to glean this info then set it to the file watcher oblect:
void CFileWatcherDlg::OnAddDir()
{
CEnterNewDir dlg;
CString str;
if(dlg.DoModal() == IDOK)
{
if(!dlg.m_sDir.IsEmpty())
{
DWORD filter=0;
if( dlg.m_bChangeAttributes)
{
filter |= COXFileWatcher::OXFileWatchChangeAttributes;
}
if( dlg.m_bChangeCreation)
{
filter |= COXFileWatcher::OXFileWatchChangeCreation;
}
if( dlg.m_bChangeDirName)
{
filter |= COXFileWatcher::OXFileWatchChangeDirName;
}
if( dlg.m_bChangeFileName)
{
filter |= COXFileWatcher::OXFileWatchChangeFileName;
}
if( dlg.m_bChangeLastAccess)
{
filter |= COXFileWatcher::OXFileWatchChangeLastAccess;
}
if( dlg.m_bChangeLastWrite)
{
filter |= COXFileWatcher::OXFileWatchChangeLastWrite;
}
if( dlg.m_bChangeSecurity)
{
filter |= COXFileWatcher::OXFileWatchChangeSecurity;
}
if( dlg.m_bChangeSize)
{
filter |= COXFileWatcher::OXFileWatchChangeSize;
}
if( fwWatcher.AddWatch( dlg.m_sDir, dlg.m_bSubTree, filter))
{
fwWatcher.EnableWindowNotification( dlg.m_sDir, this, TRUE);
...
And the notification routine should now receive the desired notifications.
For more details, refer to the COXFileWatcher
and COXFileWatchNotifier
class references in the File Management | File Watch section of the compiled HTML help documentation, and the FileWatcher sample.
Initial CodeProject release August 2007.