XTDirWatcher.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:7k
- // XTDirWatcher.cpp : implementation file
- //
- // This file is a part of the XTREME CONTROLS MFC class library.
- // (c)1998-2008 Codejock Software, All Rights Reserved.
- //
- // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
- // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
- // CONSENT OF CODEJOCK SOFTWARE.
- //
- // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
- // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
- // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
- // SINGLE COMPUTER.
- //
- // CONTACT INFORMATION:
- // support@codejock.com
- // http://www.codejock.com
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Common/XTPVC80Helpers.h" // Visual Studio 2005 helper functions
- #include "XTDefines.h"
- #include "XTShellPidl.h"
- #include "XTDirWatcher.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CXTDirWatcher
- CXTDirWatcher::CXTDirWatcher()
- {
- m_bAutoDelete = TRUE;
- m_dwMonitorEvents[0] = INVALID_HANDLE_VALUE;
- m_dwMonitorEvents[1] = INVALID_HANDLE_VALUE;
- m_dwMonitorEvents[2] = CreateEvent(NULL, TRUE, FALSE, 0); // Path was changed event.
- m_dwMonitorEvents[3] = CreateEvent(NULL, TRUE, FALSE, 0); // Stop notifications event.
- ZeroMemory(&m_tvid, sizeof(m_tvid));
- }
- CXTDirWatcher::~CXTDirWatcher()
- {
- CloseHandle(m_dwMonitorEvents[2]);
- CloseHandle(m_dwMonitorEvents[3]);
- }
- void CXTDirWatcher::StopNotifications()
- {
- SetEvent(m_dwMonitorEvents[3]);
- WaitForSingleObject(m_hThread, INFINITE);
- }
- IMPLEMENT_DYNCREATE(CXTDirWatcher, CWinThread)
- BEGIN_MESSAGE_MAP(CXTDirWatcher, CWinThread)
- //{{AFX_MSG_MAP(CXTDirWatcher)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- BOOL CXTDirWatcher::WaitPathChangedEvent()
- {
- DWORD dw = ::WaitForMultipleObjects(2,
- &m_dwMonitorEvents[2], FALSE, INFINITE);
- return dw != WAIT_OBJECT_0 + 1;
- }
- BOOL CXTDirWatcher::MonitorNotifications()
- {
- BOOL bContinueThread = TRUE;
- ::ResetEvent(m_dwMonitorEvents[2]);
- ::ResetEvent(m_dwMonitorEvents[3]);
- if (!IsPathValid(m_strFolderPath))
- return WaitPathChangedEvent();
- // Watch the directory for file creation and
- // deletion.
- m_dwMonitorEvents[0] = ::FindFirstChangeNotification(
- m_strFolderPath, // directory to watch
- FALSE, // do not watch the subtree
- FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes
- if (m_dwMonitorEvents[0] == INVALID_HANDLE_VALUE)
- return WaitPathChangedEvent();
- // Watch the tree for directory creation and
- // deletion.
- m_dwMonitorEvents[1] = ::FindFirstChangeNotification(
- m_strFolderPath, // directory to watch
- FALSE, // watch the subtree
- FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir. name changes
- if (m_dwMonitorEvents[1] == INVALID_HANDLE_VALUE)
- return WaitPathChangedEvent();
- // Change notification is set. Now wait on both notification
- // handles and refresh accordingly.
- BOOL bConinueNotifications = TRUE;
- while (bConinueNotifications)
- {
- // Wait for notification.
- DWORD dwWaitStatus = ::WaitForMultipleObjects(_countof(m_dwMonitorEvents),
- m_dwMonitorEvents, FALSE, INFINITE);
- switch (dwWaitStatus)
- {
- case WAIT_OBJECT_0:
- // A file was created or deleted in C:WINDOWS.
- // Refresh this directory and restart the
- // change notification. RefreshDirectory is an
- // application-defined function.
- RefreshFolder();
- if (!::FindNextChangeNotification(m_dwMonitorEvents[0]))
- bConinueNotifications = FALSE;
- if (!IsPathValid(m_strFolderPath))
- bConinueNotifications = FALSE;
- break;
- case WAIT_OBJECT_0 + 1:
- // A directory was created or deleted in C:.
- // Refresh the directory tree and restart the
- // change notification. RefreshTree is an
- // application-defined function.
- RefreshTree();
- if (!::FindNextChangeNotification(m_dwMonitorEvents[1]))
- bConinueNotifications = FALSE;
- if (!IsPathValid(m_strFolderPath))
- bConinueNotifications = FALSE;
- break;
- case WAIT_OBJECT_0 + 2:
- bContinueThread = TRUE;
- bConinueNotifications = FALSE;
- break;
- case WAIT_OBJECT_0 + 3:
- bContinueThread = FALSE;
- bConinueNotifications = FALSE;
- break;
- }
- }
- // Close the file change notification handle and return.
- ::FindCloseChangeNotification (m_dwMonitorEvents[0]);
- ::FindCloseChangeNotification (m_dwMonitorEvents[1]);
- m_dwMonitorEvents[0] = INVALID_HANDLE_VALUE;
- m_dwMonitorEvents[1] = INVALID_HANDLE_VALUE;
- return bContinueThread;
- }
- BOOL CXTDirWatcher::InitInstance()
- {
- BOOL bContinueThread = TRUE;
- while (bContinueThread)
- {
- bContinueThread = MonitorNotifications();
- }
- return FALSE;
- }
- BOOL CXTDirWatcher::IsPathValid(LPCTSTR lpszFolderPath)
- {
- if (_tcslen(lpszFolderPath) == 0)
- return FALSE;
- if (!DIRECTORYEXISTS_S(lpszFolderPath))
- return FALSE;
- return TRUE;
- }
- BOOL CXTDirWatcher::SetFolderPath(CWnd* pMainWnd, LPCTSTR lpszFolderPath)
- {
- if (IsPathValid(lpszFolderPath))
- {
- if (GetFolderData(lpszFolderPath, m_tvid))
- {
- m_pMainWnd = pMainWnd;
- m_strFolderPath = lpszFolderPath;
- SetEvent(m_dwMonitorEvents[2]); // Folder was changed event
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL CXTDirWatcher::SetFolderData(CWnd* pMainWnd, XT_TVITEMDATA* lpTVID)
- {
- if (!lpTVID)
- return FALSE;
- TCHAR szFolderPath[_MAX_PATH];
- if (::SHGetPathFromIDList(lpTVID->lpifq, szFolderPath))
- {
- return SetFolderPath(pMainWnd, szFolderPath);
- }
- return FALSE;
- }
- BOOL CXTDirWatcher::GetFolderData(LPCTSTR lpszFolderPath, XT_TVITEMDATA& lpTVID)
- {
- LPITEMIDLIST pidl;
- LPSHELLFOLDER pDesktopFolder;
- OLECHAR szOleChar[MAX_PATH];
- ULONG chEaten;
- ULONG dwAttributes;
- if (!IsPathValid(lpszFolderPath))
- return FALSE;
- // Get a pointer to the Desktop's IShellFolder interface.
- if (SUCCEEDED(::SHGetDesktopFolder(&pDesktopFolder)))
- {
- // IShellFolder::ParseDisplayName requires the file name be in
- // Unicode.
- #if !defined(_UNICODE)
- ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszFolderPath, -1,
- szOleChar, MAX_PATH);
- #else
- STRCPY_S(szOleChar, MAX_PATH, lpszFolderPath);
- #endif
- // Convert the path to an ITEMIDLIST.
- if (SUCCEEDED(pDesktopFolder->ParseDisplayName(NULL, NULL, szOleChar,
- &chEaten, &pidl, &dwAttributes)))
- {
- IShellFolder *psfMyFolder;
- lpTVID.lpi = lpTVID.lpifq = pidl;
- pDesktopFolder->BindToObject(lpTVID.lpifq, NULL,
- IID_IShellFolder, (LPVOID*)&psfMyFolder);
- lpTVID.lpsfParent = psfMyFolder;
- pDesktopFolder->Release();
- return TRUE;
- }
- pDesktopFolder->Release();
- }
- return FALSE;
- }
- void CXTDirWatcher::RefreshFolder()
- {
- m_pMainWnd->SendMessage(XTWM_SHELL_NOTIFY,
- SHN_XT_REFRESHFOLDER, (LPARAM)&m_tvid);
- }
- void CXTDirWatcher::RefreshTree()
- {
- m_pMainWnd->SendMessage(XTWM_SHELL_NOTIFY,
- SHN_XT_REFRESHTREE, (LPARAM)&m_tvid);
- }