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

📄 itsimplefindfiles.cpp

📁 完整的MP3播放器源码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
// $NoKeywords: $
//
// @doc INTERNAL UTILITY

#include "StdAfx.h"

#include "ITSimpleFindFiles.h"
#include "ITAPI.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Note: These special values assume that there are no FILE_ATTRIBUTE_
// values with the high bits set.
// FILE_ATTRIBUTE_SYSTEM
// FILE_ATTRIBUTE_READONLY
// FILE_ATTRIBUTE_HIDDEN
// FILE_ATTRIBUTE_DIRECTORY
// FILE_ATTRIBUTE_ARCHIVE
// FILE_ATTRIBUTE_NORMAL
// FILE_ATTRIBUTE_TEMPORARY
// FILE_ATTRIBUTE_COMPRESSED
// FILE_ATTRIBUTE_OFFLINE;

DWORD ITCSimpleFindFiles::AllAttributes = 0x01000000;
static DWORD AllAttributesSet = 0;
static DWORD AllAttributesClear = 0;

// Find all non-system files and folders.
// Includes all attributes except FILE_ATTRIBUTE_SYSTEM so
// the user doesn't search folders such as the Recycle Bin.
DWORD ITCSimpleFindFiles::DefaultAttributes = 0x02000000;
static DWORD DefaultAttributesSet = 0;
static DWORD DefaultAttributesClear = FILE_ATTRIBUTE_SYSTEM;

// Find all non-system files.
// Files don't have the FILE_ATTRIBUTE_DIRECTORY set.
DWORD ITCSimpleFindFiles::FilesOnly = 0x03000000;
static DWORD FilesOnlyAttribSet = 0;
static DWORD FilesOnlyAttribClear = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM;

// Find all non-system folders.
// Folders must have the FILE_ATTRIBUTE_DIRECTORY set.
DWORD ITCSimpleFindFiles::FoldersOnly = 0x04000000;
static DWORD FoldersOnlyAttribSet = FILE_ATTRIBUTE_DIRECTORY;
static DWORD FoldersOnlyAttribClear = FILE_ATTRIBUTE_SYSTEM;

static HDROP INVALID_DROP_HANDLE = (HDROP)INVALID_HANDLE_VALUE;

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles construction

// @mfunc Constructs a <c ITCSimpleFindFiles> object.
//
// @xref <c ITCSimpleFindFiles>
ITCSimpleFindFiles::ITCSimpleFindFiles()
{
	CommonConstruct();
}

// @mfunc Destroys a <c ITCSimpleFindFiles> object.
//
// @xref <c ITCSimpleFindFiles>
ITCSimpleFindFiles::~ITCSimpleFindFiles()
{
	Close();
}

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles attributes

BOOL ITCSimpleFindFiles::HasFileAttributes(DWORD dwFileAttributes) const
{
	return ((m_findData.dwFileAttributes & dwFileAttributes) == dwFileAttributes);
}

DWORD ITCSimpleFindFiles::GetLength() const
{
	return m_findData.nFileSizeLow;
}

DWORD ITCSimpleFindFiles::GetFileAttributes() const
{
	return m_findData.dwFileAttributes;
}

BOOL ITCSimpleFindFiles::IsSpecialFolder() const
{
	LPCTSTR lpszFileName = GetFileName();

	if (HasFileAttributes(FILE_ATTRIBUTE_DIRECTORY) && (lpszFileName[0] == '.'))
	{
		if (strcmp(lpszFileName, ".") == 0)
			return TRUE;
		else if (strcmp(lpszFileName, "..") == 0)
			return TRUE;
	}

	return FALSE;
}

CString ITCSimpleFindFiles::GetRoot() const
{
	return m_strFindRoot;
}

CString ITCSimpleFindFiles::GetFilePath() const
{
	CString strFilePath;

	// If the files we are returning are from a drag and
	// drop operation, the file paths are already fully
	// qualified. If we are getting files from the file
	// system, the file paths must be created based on
	// the search folder and the name of the current file.

	if (!IsDroppedFiles())
	{
		strFilePath = GetRoot();
		
		if (!strFilePath.IsEmpty())
		{
			ASSERT(strFilePath[strFilePath.GetLength()-1] != '\\');
			strFilePath += '\\';
		}
		
		strFilePath += GetFileName();
	}
	else
	{
		strFilePath = m_strDropFilePath;
	}

	return strFilePath;
}

CString ITCSimpleFindFiles::GetFileExt() const
{
	TCHAR szExtention[_MAX_EXT];
	_tsplitpath(GetFileName(), NULL, NULL, NULL, szExtention);
	return (szExtention[0] != '.') ? szExtention : &(szExtention[1]);
}

CString ITCSimpleFindFiles::GetFileTitle() const
{
	CString strFileTitle;
	_tsplitpath(GetFileName(), NULL, NULL, strFileTitle.GetBuffer(_MAX_PATH), NULL);
	strFileTitle.ReleaseBuffer();
	return strFileTitle;
}

LPCTSTR ITCSimpleFindFiles::GetFileName() const
{
	return m_findData.cFileName;
}

CString ITCSimpleFindFiles::GetFileFolder() const
{
	CString strFileFolder = GetFilePath();
	LPSTR lpsz = strrchr(strFileFolder.GetBuffer(0), '\\');
	if (lpsz) *lpsz = '\0';
	strFileFolder.ReleaseBuffer();
	return strFileFolder;
}

const WIN32_FIND_DATA* ITCSimpleFindFiles::GetFindData() const
{
	return &m_findData;
}

CString ITCSimpleFindFiles::GetFindPattern() const
{
	return m_strFindPattern;
}

CString ITCSimpleFindFiles::GetFindFileName() const
{
	CString strFileName = GetRoot();
	if (!strFileName.IsEmpty())
		strFileName += "\\";
	strFileName += GetFindPattern();
	return strFileName;
}

DWORD ITCSimpleFindFiles::GetUserData() const
{
	return m_dwUserData;
}

void ITCSimpleFindFiles::SetUserData(DWORD dwUserData)
{
	m_dwUserData = dwUserData;
}

void ITCSimpleFindFiles::GetFindAttributes(DWORD& dwAttribSet, DWORD& dwAttribClear) const
{
	dwAttribSet = m_dwFindAttribSet;
	dwAttribClear = m_dwFindAttribClear;
}

void ITCSimpleFindFiles::SetFindAttributes(DWORD dwAttribSet, DWORD dwAttribClear)
{
	if (dwAttribSet == ITCSimpleFindFiles::AllAttributes)
	{
		m_dwFindAttribSet = AllAttributesSet;
		m_dwFindAttribClear = AllAttributesClear;
	}
	else if (dwAttribSet == ITCSimpleFindFiles::DefaultAttributes)
	{
		m_dwFindAttribSet = DefaultAttributesSet;
		m_dwFindAttribClear = DefaultAttributesClear;
	}
	else if (dwAttribSet == ITCSimpleFindFiles::FilesOnly)
	{
		m_dwFindAttribSet = FilesOnlyAttribSet;
		m_dwFindAttribClear = FilesOnlyAttribClear;
	}
	else if (dwAttribSet == ITCSimpleFindFiles::FoldersOnly)
	{
		m_dwFindAttribSet = FoldersOnlyAttribSet;
		m_dwFindAttribClear = FoldersOnlyAttribClear;
	}
	else
	{
		m_dwFindAttribSet = dwAttribSet;
		m_dwFindAttribClear = dwAttribClear;
	}
}

BOOL ITCSimpleFindFiles::IsDroppedFiles() const
{
	return (m_hDropInfo != INVALID_DROP_HANDLE);
}

CString ITCSimpleFindFiles::GetTypeName() const
{
	CString strTypeName;

	SHFILEINFO sfi;
	if (SHGetFileInfo(0, &sfi, SHGFI_TYPENAME))
	{
		strTypeName = sfi.szTypeName;
	}

	// szTypeName may be an empty string. If so, we build the
	// type based on the file extension (i.e. 'DAT File'). If
	// there is no file extension, just use the word 'File'.

	if (strTypeName.IsEmpty())
	{
		strTypeName = GetFileExt();
		strTypeName.MakeUpper(); // Extension is shown in uppercase
		strTypeName += (strTypeName.IsEmpty()) ? "File" : " File";
	}

	return strTypeName;
}

DWORD ITCSimpleFindFiles::SHGetFileInfo(DWORD dwFileAttributes,
	SHFILEINFO FAR *psfi, UINT uFlags) const
{
	return ::SHGetFileInfo(GetFilePath(), dwFileAttributes, 
		psfi, sizeof(SHFILEINFO), uFlags);
}

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles operations

void ITCSimpleFindFiles::NewSearch(CString strPattern,
	DWORD dwFindAttributes)
{
	ITCLIB::TrimString(strPattern);

	if (strPattern.IsEmpty())
		strPattern = "*.*";

	CString strFindRoot;
	CString strFindPattern;

	const int chPattern = strPattern.ReverseFind('\\');
	if (chPattern >= 0)
	{
		strFindRoot = strPattern.Left(chPattern);
		const int nLength = strPattern.GetLength() - chPattern - 1;
		strFindPattern = strPattern.Right(nLength);
	}
	else
	{
		strFindRoot.Empty();
		strFindPattern = strPattern;
	}

	NewSearch(strFindRoot, strFindPattern, dwFindAttributes);
}

void ITCSimpleFindFiles::NewSearch(CString strFolder,
	CString strPattern, DWORD dwFindAttributes)
{
	ASSERT(m_hFindFile == INVALID_HANDLE_VALUE);

	CommonConstruct();

	ITCLIB::TrimString(strFolder);
	ITCLIB::TrimString(strPattern);

	if (strPattern.IsEmpty())
		strPattern = "*.*";

	m_strFindPattern = strPattern;
	
	SetFindAttributes(dwFindAttributes, 0);

	// If the folder is a drive specification such as "C:"
	// we can't call fullpath() because it will convert it
	// to the current directory for that drive and they
	// really want to search the entire drive.
	BOOL bSearchDrive = FALSE;
	if (!strFolder.IsEmpty())
		bSearchDrive = (strFolder[strFolder.GetLength()-1] == ':');

	if (!bSearchDrive)
	{
		LPTSTR lpszRoot = m_strFindRoot.GetBufferSetLength(_MAX_PATH);
		_tfullpath(lpszRoot, strFolder, _MAX_PATH);
		if (lpszRoot[lstrlen(lpszRoot)-1] == '\\')
			lpszRoot[lstrlen(lpszRoot)-1] = '\0';
		m_strFindRoot.ReleaseBuffer();
	}
	else
	{
		m_strFindRoot = strFolder;
	}
}

void ITCSimpleFindFiles::NewSearch(HDROP hDropInfo,
	DWORD dwFindAttributes)
{
	ASSERT(hDropInfo != NULL);
	ASSERT(m_hFindFile == INVALID_HANDLE_VALUE);

	CommonConstruct();

	m_hDropInfo = hDropInfo;
	m_uDropIndex = 0;
	m_uMaxDropIndex = ::DragQueryFile(m_hDropInfo, (UINT)-1, NULL, 0);

	SetFindAttributes(dwFindAttributes, 0);
}

void ITCSimpleFindFiles::NewSearch(const ITCSimpleFindFiles& rhs)
{
	ASSERT(m_hDropInfo == INVALID_DROP_HANDLE);
	ASSERT(m_hFindFile == INVALID_HANDLE_VALUE);

	CommonConstruct();

	m_uDropIndex = 0;
	m_uMaxDropIndex = rhs.m_uMaxDropIndex;
	m_dwUserData = rhs.m_dwUserData;
	m_dwFindAttribSet = rhs.m_dwFindAttribSet;
	m_dwFindAttribClear = rhs.m_dwFindAttribClear;
	m_hDropInfo = rhs.m_hDropInfo;
	m_hFindFile = rhs.m_hFindFile;
	m_strFindRoot = rhs.m_strFindRoot;
	m_strFindPattern = rhs.m_strFindPattern;
	m_strDropFilePath = rhs.m_strDropFilePath;

	CopyMemory(&m_findData, &(rhs.m_findData), sizeof(WIN32_FIND_DATA));
}

BOOL ITCSimpleFindFiles::NextFile()
{
	return (IsDroppedFiles()) ? NextDropFile() : NextFindFile();
}

void ITCSimpleFindFiles::Close()
{
	if (m_hFindFile != INVALID_HANDLE_VALUE)
	{
		VERIFY(::FindClose(m_hFindFile));
		m_hFindFile = INVALID_HANDLE_VALUE;
	}

	if (m_hDropInfo != INVALID_DROP_HANDLE)
	{
		m_uDropIndex = 0;
		m_uMaxDropIndex = 0;
		m_hDropInfo = INVALID_DROP_HANDLE;
	}
}

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles overridables

BOOL ITCSimpleFindFiles::OnFilterFile() const
{
	// Skip the special folders "." and ".." and any files
	// that have or don't have the attributes we are looking for.

	BOOL bMatch = TRUE;

	bMatch &= (!IsSpecialFolder());
	bMatch &= ((m_findData.dwFileAttributes & m_dwFindAttribSet) == m_dwFindAttribSet);
	bMatch &= ((m_findData.dwFileAttributes & m_dwFindAttribClear) == 0);

	return bMatch;
}

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles implementation

void ITCSimpleFindFiles::CommonConstruct()
{
	m_hFindFile = INVALID_HANDLE_VALUE;
	m_hDropInfo = INVALID_DROP_HANDLE;
	m_uDropIndex = 0;
	m_dwUserData = 0;
	m_uMaxDropIndex = 0;
	m_dwFindAttribSet = 0; // Match all files
	m_dwFindAttribClear = 0; // Match all files

	m_strFindRoot.Empty();
	m_strFindPattern = "*.*";
	m_strDropFilePath.Empty();

	::ZeroMemory(&m_findData, sizeof(WIN32_FIND_DATA));
}

BOOL ITCSimpleFindFiles::NextFindFile()
{
	::ZeroMemory(&m_findData, sizeof(WIN32_FIND_DATA));

	if (m_hFindFile == INVALID_HANDLE_VALUE)
	{
		// The first time we are called, attempt to open the
		// find and see if the first file is valid.

		m_hFindFile = ::FindFirstFile(GetFindFileName(), &m_findData);
		if (m_hFindFile != INVALID_HANDLE_VALUE)
			if (OnFilterFile())
				return TRUE;
	}

	if (m_hFindFile != INVALID_HANDLE_VALUE)
	{
		// If the first file is not valid, or when we are called
		// again, search until we find the next valid file.

		do
		{
			if (!::FindNextFile(m_hFindFile, &m_findData))
				return FALSE;

		} while (!OnFilterFile());
	}

	return (m_hFindFile != INVALID_HANDLE_VALUE);
}

BOOL ITCSimpleFindFiles::NextDropFile()
{
	if (m_hDropInfo != INVALID_DROP_HANDLE)
	{
		do
		{
			if (!DragQueryFile())
				return FALSE;

		} while (!OnFilterFile());
	}

	return (m_hDropInfo != INVALID_DROP_HANDLE);
}

BOOL ITCSimpleFindFiles::DragQueryFile()
{
	ASSERT(m_hDropInfo != INVALID_DROP_HANDLE);

	BOOL bValidFile = FALSE; // Assume failure

	::ZeroMemory(&m_findData, sizeof(WIN32_FIND_DATA));

	if (m_uDropIndex < m_uMaxDropIndex)
	{
		LPSTR lpszFile = m_strDropFilePath.GetBufferSetLength(_MAX_PATH);

		VERIFY(::DragQueryFile(m_hDropInfo, m_uDropIndex++,
			lpszFile, _MAX_PATH) < _MAX_PATH);

		m_strDropFilePath.ReleaseBuffer();

		bValidFile = (::FindFirstFile(m_strDropFilePath,
			&m_findData) != INVALID_HANDLE_VALUE);
	}
	else
	{
		::SetLastError(ERROR_NO_MORE_FILES);
	}

	if (!bValidFile)
		m_strDropFilePath.Empty();

	return bValidFile;
}

/////////////////////////////////////////////////////////////////////////////
// ITCSimpleFindFiles diagnostics

#ifdef _DEBUG
void ITCSimpleFindFiles::AssertValid() const
{
	CObject::AssertValid();

	if (m_hFindFile != INVALID_HANDLE_VALUE)
	{
		ASSERT(m_hDropInfo == INVALID_DROP_HANDLE);
	}

	if (m_hDropInfo != INVALID_DROP_HANDLE)
	{
		ASSERT(m_hFindFile == INVALID_HANDLE_VALUE);
	}
}

void ITCSimpleFindFiles::Dump(CDumpContext& dc) const
{
	CObject::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(ITCSimpleFindFiles, CObject)

⌨️ 快捷键说明

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