/** * @file XTPDirWatcher.h * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ /** @cond */ #if !defined(__XTPDIRWATCHER_H__) # define __XTPDIRWATCHER_H__ /** @endcond */ # if _MSC_VER > 1000 # pragma once # endif // _MSC_VER > 1000 # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" /** * @brief * The CXTPDirWatcher is a thread class that will monitor a specified * path for file and directory changes to occur. * @details * Whenever an item is created, deleted or renamed, the thread will send a * notification to its owner in the form of a WM_XTP_SHELL_NOTIFY message. * The WPARAM value for the notification will be set to SHN_XTP_TREESELCHANGE * if the folder list contents require updating or SHN_XTP_CONTENTSCHANGED * if the tree contents require updating. The LPARAM value is set to the address * of an XTP_TVITEMDATA structure that contains information that the path * monitored. * Example: * To use CXTPDirWatcher, add a CXTPDirWatcher* m_pDirThread member * to your class and instantiate a new thread using AfxBeginThread: * *
 * // Start the directory monitoring thread.
 * m_pDirThread = (CXTPDirWatcher*)AfxBeginThread(RUNTIME_CLASS(CXTPDirWatcher),
 * THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
 * 
* You can then specify what directory you wish to monitor by calling SetFolderData * or SetFolderPath: *
 * // Specify the folder to monitor.
 * m_pDirThread->SetFolderData(this, lpTVID);
 * m_pDirThread->ResumeThread();
 * 
* * You can add a message handler to the window receiving messages and handle * your change event notifications. The thread will send two notifications. * The wParam value indicates what event has occurred. If wParam equals * HN_XT_REFRESHFOLDER, then this indicates that the folder list has changed * and needs to be updated. If wParam equals SHN_XTP_REFRESHTREE, then * this indicates the folder tree has changed and needs to be updated. The * lParam value represents a pointer to an XTP_TVITEMDATA structure for the * folder: * *
 * BEGIN_MESSAGE_MAP(CNotifyWnd, CWnd)
 *    //{{AFX_MSG_MAP(CNotifyWnd)
 *    ON_MESSAGE(WM_XTP_SHELL_NOTIFY, OnUpdateShell)
 *    //}}AFX_MSG_MAP
 * END_MESSAGE_MAP()
 *
 * LRESULT CNotifyWnd::OnUpdateShell(WPARAM wParam, LPARAM lParam)
 * {
 *    switch (wParam)
 *    {
 *       case SHN_XTP_REFRESHFOLDER:
 *       case SHN_XTP_REFRESHTREE:
 *       {
 *          // Directory monitory thread has issued an update notification,
 *          // refresh the list control.
 *          XTP_TVITEMDATA*  lpTVID = (XTP_TVITEMDATA*)lParam;
 *          _ASSERTE(lpTVID);
 *
 *          PopulateListView(lpTVID, lpTVID->lpsfParent);
 *          break;
 *       }
 *
 *       default:
 *          break;
 *    }
 *
 *    return 0;
 * }
 * 
* * When you are finished using the CXTPDirWatcher thread, you will need to * free the memory associated with the object. To do so, you can use the * SAFE_DELETE macro like so: * *
 * SAFE_DELETE(m_pDirThread);
 * 
* * The CXTPDirWatcher class is used internally by the CXTPShellListCtrl and * CXTPShellListView classes to handle refreshing the list when a file or * directory change occurs. */ class _XTP_EXT_CLASS CXTPDirWatcher : public CXTPWinThread { /** @cond */ DECLARE_DYNCREATE(CXTPDirWatcher) /** @endcond */ public: /** * @brief * Constructs a CXTPDirWatcher object. */ CXTPDirWatcher(); protected: /** * @brief * Destroys a CXTPDirWatcher object, handles cleanup and deallocation. */ virtual ~CXTPDirWatcher(); public: /** * @brief * Call this member function to monitor the directory specified by strPath. * @param pMainWnd Pointer to the window to receive change notifications. * @param lpszFolderPath Full path of the directory to monitor. * @param bWatchSubtree Monitors the directory tree rooted at the specified * directory. * @return * TRUE if successful, otherwise FALSE. */ BOOL SetFolderPath(CWnd* pMainWnd, LPCTSTR lpszFolderPath, BOOL bWatchSubtree = FALSE); /** * @brief * Call this member function to retrieve the full path to the currently * monitored directory. * @return * A CString object representing the full path to the currently monitored * directory. */ CString GetFolderPath() const; /** * @brief * Call this member function to monitor the directory using a pointer * to an XTP_TVITEMDATA pointer. * @param pMainWnd Pointer to the window to receive update notifications. * @param lpTVID Pointer to the tree view item data. * @return * TRUE if successful, otherwise FALSE. */ BOOL SetFolderData(CWnd* pMainWnd, XTP_TVITEMDATA* lpTVID); /** * @brief * This member function is called to return a pointer * to the XTP_TVITEMDATA structure for the directory that is currently * monitored. In the second version, this function constructs an * XTP_TVITEMDATA structure from the specified path. * @return * A pointer to an XTP_TVITEMDATA structure. */ XTP_TVITEMDATA* GetFolderData(); /** * @brief * This function constructs an XTP_TVITEMDATA structure from the specified path. * @param lpszFolderPath Full path to directory. * @param lpTVID Reference to tree view item data. * @return * TRUE if successful, otherwise FALSE. */ BOOL GetFolderData(LPCTSTR lpszFolderPath, XTP_TVITEMDATA& lpTVID); /** * @brief * Call this member function to determine if the specified path * is a valid directory name. * @param lpszFolderPath Full path to directory. * @return * TRUE if the path is valid, otherwise FALSE. */ BOOL IsPathValid(LPCTSTR lpszFolderPath); /** * @brief * Finishes Notification loop. */ void StopNotifications(); public: /** @cond */ //{{AFX_VIRTUAL(CXTPDirWatcher) virtual BOOL InitInstance(); //}}AFX_VIRTUAL /** @endcond */ protected: /** * @brief * This member function is called by the thread whenever the monitored * directory list needs to be refreshed. */ virtual void RefreshFolder(); /** * @brief * This member function is called by the thread whenever the monitored * directory tree needs to be refreshed. */ virtual void RefreshTree(); /** * @brief * Worker method with main notification loop. * @return * TRUE if succcessful, otherwise FALSE. */ BOOL MonitorNotifications(); /** * @brief * Waits for the developer to set a new path to monitor. * @return * TRUE if succcessful, otherwise FALSE. */ BOOL WaitPathChangedEvent(); protected: /** @cond */ DECLARE_MESSAGE_MAP() //{{AFX_MSG(CXTPDirWatcher) //}}AFX_MSG /** @endcond */ protected: HANDLE m_dwMonitorEvents[4]; /**< Change event handles. */ CString m_strFolderPath; /**< Path that is monitored. */ XTP_TVITEMDATA m_tvid; /**< Tree view item data. */ BOOL m_bWatchSubtree; /**< Monitors the directory tree. */ }; ///////////////////////////////////////////////////////////////////////////// /** @cond */ AFX_INLINE CString CXTPDirWatcher::GetFolderPath() const { return m_strFolderPath; } AFX_INLINE XTP_TVITEMDATA* CXTPDirWatcher::GetFolderData() { return &m_tvid; } /** @endcond */ # include "Common/Base/Diagnostic/XTPEnableNoisyWarnings.h" /** @cond */ #endif // !defined(__XTPDIRWATCHER_H__) /** @endcond */