Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The Ultimate Toolbox File Watcher

0.00/5 (No votes)
25 Aug 2007 1  
An easy to use file watcher from the Ultimate Toolbox

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:

  1. 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.

  1. 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"


/////////////////////////////////////////////////////////////////////////////


// CFileWatcherDlg dialog


class CFileWatcherDlg : public CDialog
{
    COXFileWatcher    fwWatcher;

// Construction


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)
    //{{AFX_MSG_MAP(CFileWatcherDlg)


    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 )    // add this handler


    //}}AFX_MSG_MAP

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)
// --- In  : wP: the ID of the Notifier object


// --- Out : 


// --- Returns : ...


// --- Effect : Responds to the notification message from FileWatcher


{
    CString str;

    COXFileWatchNotifier fwnNotifier;
    fwnNotifier = fwWatcher.GetFileWatchNotifier( wP);
    ...     // code removed //


    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() 
// --- In  : 


// --- Out : 


// --- Returns : 


// --- Effect : Responds to the 'Add dir...' button


{
    CEnterNewDir dlg;
    CString str;

    // Gets the watched directory and filter


    if(dlg.DoModal() == IDOK)
    {
        if(!dlg.m_sDir.IsEmpty())
        {
            DWORD filter=0;

            // Determines the watch filter


            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))
            {
                // If the directory is added set the window for notifications


                fwWatcher.EnableWindowNotification( dlg.m_sDir, this, TRUE);
            ... // code removed

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.

History

Initial CodeProject release August 2007.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here