⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filechangenotify.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
字号:
// FileZilla - a Windows ftp client

// Copyright (C) 2002-2005 - Tim Kosse <tim.kosse@gmx.de>

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// FileChangeNotify.cpp: implementation of the CFileChangeNotify class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FileChangeNotify.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFileChangeNotify::CFileChangeNotify()
{
	m_isWaiting = false;
	m_notifyWnd = NULL;
	m_hThread = INVALID_HANDLE_VALUE;
	m_hEvent = INVALID_HANDLE_VALUE;
	m_pHH = NULL;
}	

CFileChangeNotify::~CFileChangeNotify()
{
	StopNotify();
}

int CFileChangeNotify::AddWatch(LPCTSTR lpPathName, BOOL bWatchSubtree, DWORD dwNotifyFilter)
{
	if (m_isWaiting)
		return -1;
	HANDLE handle = FindFirstChangeNotification(lpPathName, bWatchSubtree, dwNotifyFilter);
	if (handle == INVALID_HANDLE_VALUE)
		return -1;
	m_chHandle.push_back(handle);
	return 0;
}

DWORD WINAPI CFileChangeNotify::WatchingThread(LPVOID param)
{
	CFileChangeNotify *pNotify = (CFileChangeNotify *)param;
	
	std::vector<HANDLE> &handles = pNotify->m_chHandle;

	int objnums = handles.size() + 1;

	while (true)
	{
		// Send notifications no more than once per second
		if (WaitForSingleObject(pNotify->m_pHH[objnums - 1], 1000) != WAIT_TIMEOUT)
			return 0;

		// Wait for notification.
		DWORD status = WaitForMultipleObjects(objnums, pNotify->m_pHH, FALSE, INFINITE); 
		if (status == (WAIT_OBJECT_0 + objnums - 1) ||
			status == (WAIT_ABANDONED_0 + objnums - 1))
			return 0;

		int idx = status - WAIT_OBJECT_0;
		::SendMessage(pNotify->m_notifyWnd, WM_REQUEST_REFRESH, idx, NULL);
		if (FindNextChangeNotification(pNotify->m_pHH[idx]) == FALSE)
			break;
	}

	return 0;
}

int CFileChangeNotify::StartNotify()
{
	if (m_isWaiting) 
		return -1;

	if (!m_notifyWnd)
		return -1;


	m_pHH = new HANDLE[m_chHandle.size() + 1];
	for (unsigned int i = 0; i < m_chHandle.size(); i++)
		m_pHH[i] = m_chHandle[i];

	// At the topmost index, but the event that will be signaled when the thread should quit
	m_hEvent = CreateEvent(0, false, false, 0);
	if (m_hEvent == INVALID_HANDLE_VALUE)
		return -1;
	m_pHH[m_chHandle.size()] = m_hEvent;

	m_hThread = CreateThread(NULL, NULL, WatchingThread, (LPVOID)this, NULL, NULL);
	if (m_hThread == INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hEvent);
		m_hEvent = INVALID_HANDLE_VALUE;
		return -1;
	}

	m_isWaiting = true;		// enter the watching mode

	return 0;
}

void CFileChangeNotify::StopNotify()
{
	m_isWaiting = false;

	if (m_hThread != INVALID_HANDLE_VALUE)
	{
		SetEvent(m_hEvent);
		if (WaitForSingleObject(m_hThread, 1000) == WAIT_TIMEOUT)
			TerminateThread(m_hThread, 0);
		CloseHandle(m_hThread);
		m_hThread = INVALID_HANDLE_VALUE;
	}
	if (m_hEvent != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hEvent);
		m_hEvent = INVALID_HANDLE_VALUE;
	}

	m_notifyWnd = NULL;
	
	for (unsigned int i = 0; i < m_chHandle.size(); i++)
		CloseHandle(m_chHandle[i]);

	m_chHandle.clear();
	delete [] m_pHH;
	m_pHH = NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -