CFileWatch

Environment: VC6 SP4 Win2000

This class helps you to monitor files like in the DevStudio. If the file is modified outside, a message box pops up and lets you choose between ignoring modifications or reloading the data, discarding all changes.
If the file is modified, a message is send either to the specified view or to the first view of a specified document. The message handler will call the reload function of the document class. The class should be thread save.

Things you have to change in your ViewClass and DocumentClass:

In your document class header file:

class CFileWatchAppDoc : public CRichEditDoc
{
    ....
public:
    void OnFileReload();
protected:
    DWORD m_hFileWatch;
    void AddToFileWatch();
};

In your document class source file:

#include "FileWatch.h"

CFileWatchAppDoc::CFileWatchAppDoc()
{
    m_hFileWatch = NULL;
}

CFileWatchAppDoc::~CFileWatchAppDoc()
{
    CFileWatch::RemoveHandle(m_hFileWatch);
}

BOOL CFileWatchAppDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
    CFileWatch::RemoveHandle(m_hFileWatch);
    BOOL bSuccess = 
    CRichEditDoc::OnSaveDocument(lpszPathName);
    AddToFileWatch();    
    return bSuccess; 
} 

void CFileWatchAppDoc::SetPathName(LPCTSTR lpszPathName,
                                       BOOL bAddToMRU) 
{
    CFileWatch::RemoveHandle(m_hFileWatch); 
    CRichEditDoc::SetPathName(lpszPathName, bAddToMRU);
    AddToFileWatch(); 
} 

void CFileWatchAppDoc::AddToFileWatch()
{
    m_hFileWatch = CFileWatch::AddFileFolder(lpszPathName, NULL, this); 
    CFileWatch::SetAutoReload(m_hFileWatch, 
   &((CYourApp*)AfxGetApp())->m_bAutoReloadDocTypeXY);
}

void CFileWatchAppDoc::OnFileReload()
{
    // your reload code
    ...
    UpdateAllViews(NULL);
}

In your view class header file:

class CFileWatchAppView : public CRichEditView {     ... protected:     //{{AFX_MSG(CFileWatchAppView)     afx_msg LRESULT OnFileWatchNotification(WPARAM wParam,     LPARAM lParam);     //}}AFX_MSG     DECLARE_MESSAGE_MAP() };

In your view class source file:
#include "FileWatch.h"

BEGIN_MESSAGE_MAP(CFileWatchAppView, CRichEditView)
  //{{AFX_MSG_MAP(CFileWatchAppView)
  ON_REGISTERED_MESSAGE(CFileWatch::m_msgFileWatchNotify,
                        OnFileWatchNotification)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

LRESULT CFileWatchAppView::OnFileWatchNotification(WPARAM wParam, 
                                                   LPARAM lParam)
{
    CString sPathName = CString((LPCTSTR)lParam);
    DWORD dwData = (DWORD)wParam;

   GetDocument()->OnFileReload();

    return 0;
}

In your mainframe class source file:

#include "FileWatch.h"

void CMainFrame::OnClose() 
{
    CFileWatch::Stop();
    CMDIFrameWnd::OnClose();
}

Add Non-document files to the watch:

Non-document files, which should be monitored, can be added to the watch, but must be associated with a view class. Use DWORD dwData or the file name to distinguish, which file has been changed.
#include "FileWatch.h"

void class::xy()
{
   ...
   DWORD hHandle = CFileWatch::AddFileFolder(LPCTSTR lpszFileName,
                HWND hWnd, CDocument* pDocument=NULL, DWORD dwData);
   ...
}

LRESULT CYourView::OnFileWatchNotification(WPARAM wParam, 
                                           LPARAM lParam)
{
    CString sPathName = CString((LPCTSTR)lParam);
    DWORD dwData = (DWORD)wParam;

    if (sPathName == GetDocument()->GetPathName()) 
      GetDocument()->OnFileReload();
    else
       ...

    return 0;
}

ATTENTION!

Not all file systems record write time in the same manner. For example, on Windows NT FAT, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of one day (really, the access date). On NTFS, access time has a resolution of one hour. Furthermore, FAT records times on disk in local time, while NTFS records times on disk in UTC, so it is not affected by changes in time zone or daylight saving time. I have no information about the resolution of the write time in FAT or FAT32. However, if the file is modified several times in the same time window, only one notification can be detected!!!

Download latest version here.

Downloads

Download demo project - 60 Kb
Download source - 3 Kb


Comments

  • "File Modified Outside Source Editor" Warning Message

    Posted by Legacy on 10/18/2003 12:00am

    Originally posted by: Carl Owenby

    October 18, 2003

    Re: Microsoft Knowledge Base Article - 174942

    "File Modified Outside Source Editor" Warning Message

    I believe I have discovered a cause of this warning in a specific situation. I encountered this message while using Microsoft Visual C++ .NET. The message box appears after the "Build Solution" command is complete, following editing of a source file using the native .NET editor.

    In this case, the project and source files were stored on a network file server. A tape backup job was running at the time on the file server when I encountered the warning. I moved the project and source files to the local hard drive on the workstation and didn't get the error message. I moved the project and source files back to the file server after the tape backup job completed and didn't get the warning then either.

    Under Microsoft Visual C++ .NET, the window title is Microsoft Development Environment. The window displays the full path file name followed by the following message:
    This file has been modified outside of the source editor.
    Do you want to reload it?
    The command buttons are: Yes, Yes to All, No, No to All.

    The bottom line is that Visual Studio .NET may erroneously detect that a file has been modified outside of the source editor, in situations when there is a delay between the time the file is saved and when it is actually written to the network drive.

    Carl Owenby

    Reply
  • have you ever tested what you have written?

    Posted by Legacy on 11/24/2002 12:00am

    Originally posted by: roman thiel

    i have just a few problems with the implementation.

    Reply
  • File I/O operator

    Posted by Legacy on 03/26/2002 12:00am

    Originally posted by: jxz


    I don't know how to write trace data into log file.

    For example, when i start a thread in program,i want to

    know the steps of thread work,it should be written to log file.

    Reply
  • Prevent user from editing my log file.

    Posted by Legacy on 01/25/2002 12:00am

    Originally posted by: Abhishek

    My application generats an event log, This log has some information which should not be modified outside of my application. Is there any way I can prevent the text file from being edited anywhere outside my application???

    Reply
  • Comments and questions

    Posted by Legacy on 06/13/2001 12:00am

    Originally posted by: Andrew Phillips

    This is a very useful facility but I am a bit puzzled by a few things. I guess there is a reason.

    1. Is it necessary to call RegisterWindowMessage? I thought that was only needed for inter-app messages not for inter-thread.

    2. Why send the notify message to a view window? The main frame or child frame window seems more appropriate. Does this avoid some problem?

    3. Why handle the message in the view? The document seems the logical place to load a file. Does this avoid some problem?

    A few other comments:

    1. If an open file is changed when a modal dialog is open in the FileWatchApp (eg the File Open dialog) then the message is received and handled OK. But after that you can happily edit files while the (now apprently modeless) dialog is still open. I have seen this sort of thing (and worse) before due to the horrible way MFC/Windows works.

    2. It would be far more flexible if the CFileSwap class was decoupled from CDocument/CView. Instead of saving a document ptr in FILEWATCHITEM why not a CWnd ptr or HWND?

    3. I'm sure m_csDataLock is necessary but you should try to minimise the stuff that is done in a critical section. In particular it is not a good idea to invoke a dialog while you have it locked.

    4. Also when m_bStopWatch is set the break from the loop means the critical section remains locked. You can probably get away with these things for now but you never know when they'll bite you.

    5. I'm picking nits but its probably better to use CompareFileTime() to compare FILETIMEs rather than convert to 64 bit ints and compare those.


    Reply
  • ASSERTs on Network files

    Posted by Legacy on 06/07/2001 12:00am

    Originally posted by: Neville Franks

    Opening a file using a UNC on a Network drive raises the ASSERT on line 306 of FileWatch.cpp

    My understanding is that File Change Notification are of very limited use, as they don't work on remote files.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds