Click here to Skip to main content
15,879,535 members
Articles / Desktop Programming / MFC

CDirectoryChangeWatcher - ReadDirectoryChangesW all wrapped up

Rate me:
Please Sign up or sign in to vote.
4.92/5 (114 votes)
11 May 2002 2.1M   39.4K   365  
This class wraps up ReadDirectoryChangesW.
// DelayedDirectoryChangeHandler.h: interface for the CDelayedDirectoryChangeHandler2 class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DELAYEDDIRECTORYCHANGEHANDLER_H__F20EC22B_1C79_403E_B43C_938F95723D45__INCLUDED_)
#define AFX_DELAYEDDIRECTORYCHANGEHANDLER_H__F20EC22B_1C79_403E_B43C_938F95723D45__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CDirectoryChangeWatcher;
class CDirectoryChangeHandler;
class CDelayedDirectoryChangeHandler;

class CDelayedDirectoryChangeNotification
//
//	 A class to help dispatch the change notifications to the main thread.
//
{
private:
	CDelayedDirectoryChangeNotification();//not implemented
public:
	CDelayedDirectoryChangeNotification(CDelayedDirectoryChangeHandler * pDelayedHandler);
	~CDelayedDirectoryChangeNotification();

	//
	//
	void PostOn_FileAdded(const CString & strFileName);
	void PostOn_FileRemoved(const CString & strFileName);
	void PostOn_FileNameChanged(const CString & strOldName, const CString & strNewName);
	void PostOn_FileModified(const CString & strFileName);
	void PostOn_ReadDirectoryChangesError(DWORD dwError);

	void DispatchNotificationFunction();

protected:
	enum eFunctionToDispatch{	eFunctionNotDefined,
								eOn_FileAdded, 
								eOn_FileRemoved, 
								eOn_FileModified,
								eOn_FileRenamed,
								eOn_ReadDirectoryChangesError
	};	
	void PostNotification();
private:
	friend class CDelayedDirectoryChangeHandler;
	CDelayedDirectoryChangeHandler * m_pDelayedHandler;

	//
	//	Members to help implement DispatchNotificationFunction
	//
	//
	eFunctionToDispatch m_eFunctionToDispatch;
	CString	m_strFileName1,
			m_strFileName2;
	DWORD m_dwError;
};


//////////////////////////////////////////////////////////////////////////
//
//	This class makes it so that a file change notification is executed in the
//	context of the main thread, and not the worker thread.
//
//
//	It works by creating a hidden window.  When it receieves a notification
//	via one of the On_Filexxx() functions, a message is posted to this window.
//	when the message is handled, the notification is fired again in the context
//	of the main thread, or whichever thread that called CDirectoryChangeWatcher::WatchDirectory()
//
//

class CDelayedDirectoryChangeHandler : public CDirectoryChangeHandler
//	Helps all notifications become handled by the main
//	thread by posting messages to a window created in the main
//	thread.
//	Message is dispatched when message is handled by
//  that window.
//
//  The 'main' thread is the one that called CDirectoryChangeWatcher::WatchDirectory()
{
public:
	CDelayedDirectoryChangeHandler( CDirectoryChangeHandler * pRealHandler);
	~CDelayedDirectoryChangeHandler();
	
	
	CDirectoryChangeHandler * GetRealChangeHandler()const { return m_pRealHandler; }
	CDirectoryChangeHandler * & GetRealChangeHandler(){ return m_pRealHandler; }
protected:
	//These functions are called when the directory to watch has had a change made to it
	virtual void On_FileAdded(const CString & strFileName);
	virtual void On_FileRemoved(const CString & strFileName);
	virtual void On_FileModified(const CString & strFileName);
	virtual void On_FileNameChanged(const CString & strOldFileName, const CString & strNewFileName);
	virtual void On_ReadDirectoryChangesError(DWORD dwError);
	
	void SetChangedDirectoryName(const CString & strChangedDirName);
	const CString & GetChangedDirectoryName()const;
	void DispatchNotificationFunction(CDelayedDirectoryChangeNotification * pNotification);
	//
	//	A member class that controls a window to receive messages
	//
	class CDelayedNotificationWindow
		//
		//	No matter how many of these objects are,
		//	there will always be only one of the actual windows 
		//	in existance. (per thread that calls CDirectoryChangeWatcher::WatchDirectory())
		//
	{
	public:
		CDelayedNotificationWindow()
		{
			AddRef();
		}
		~CDelayedNotificationWindow(){
			Release();
		}
		
		void PostNotification(CDelayedDirectoryChangeNotification * pNotification);
	private:
		long AddRef();		//	the window handle is reference counted
		long Release();		//
		static long s_nRefCnt;
		static HWND s_hWnd;
		static BOOL s_bRegisterWindow;
		BOOL RegisterWindowClass(LPCTSTR szClassName);
		BOOL CreateNotificationWindow();
	};//end class CDelayedNotificationWindow
	friend class CDelayedDirectoryChangeNotification;
	friend class CDirectoryChangeWatcher;
	
	CDelayedNotificationWindow m_DelayWindow;
private:
		
	CDelayedDirectoryChangeNotification * GetNotificationObject();
	void DisposeOfNotification(CDelayedDirectoryChangeNotification * pNotification);
		
	CDirectoryChangeHandler * m_pRealHandler;	
};




#endif // !defined(AFX_DELAYEDDIRECTORYCHANGEHANDLER_H__F20EC22B_1C79_403E_B43C_938F95723D45__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions