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

📄 mtlmisc.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:
#ifndef __MTLMISC_H__
#define __MTLMISC_H__

// MTL Version 0.03
// Copyright (C) 2000 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// Last updated: August 16, 2000

#ifndef __ATLCTRLS_H__
	#error mtlmisc.h requires atlctrls.h to be included first
#endif

#ifndef _SHLOBJ_H_
	#error mtlmisc.h requires shlobj.h to be included first
#endif

#pragma once

#include <algorithm>

namespace MTL
{
/////////////////////////////////////////////////////////////////////////////
// Tips
inline bool MtlIsCrossRect(const CRect& rc1, const CRect& rc2)
{
	CRect rcCross = rc1 & rc2;
	return rcCross.IsRectEmpty() ? false : true;
}

inline int MtlComputeWidthOfText(const CString& strText, HFONT hFont)
{
	if (strText.IsEmpty())
		return 0;

	CWindowDC dc(NULL);
	CRect rcText(0, 0, 0, 0);
	HFONT hOldFont = dc.SelectFont(hFont);
	dc.DrawText(strText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
	dc.SelectFont(hOldFont);

	return rcText.Width();
}
/////////////////////////////////////////////////////////////////////////////
// Algorithm
inline bool __MtlIsLastChar(const CString& str, TCHAR ch)
{
	if (str.GetLength() <= 0)
		return false;

#ifdef _UNICODE
	if (str[str.GetLength() - 1] == ch)
		return true;
	else
		return false;
#else
	if (str[str.GetLength() - 1] == ch && !_IsDBCSTrailByte(str, str.GetLength() - 1))
		return true;
	else
		return false;
#endif
}

inline TCHAR* Mtl_strstr (
		const TCHAR * str1,
		const TCHAR * str2
		)
{
		TCHAR *cp = (TCHAR *) str1;
		TCHAR *s1, *s2;

		if ( !*str2 )
			return((TCHAR *)str1);

		while (*cp)
		{
				s1 = cp;
				s2 = (TCHAR *) str2;

				/*
				 * MBCS: ok to ++ since doing equality comparison.
				 * [This depends on MBCS strings being "legal".]
				 */
				while ( *s1 && *s2 && (*s1 == *s2) )
					s1++, s2++;

				if (!*s2)
						return(cp);

				cp = ::CharNext(cp);
		}

		return(NULL);
}

// CString::Find is too late...
inline int __MtlFind(LPCTSTR lpszSrc, LPCTSTR lpszSub)
{
	// find first matching substring
	LPTSTR lpsz = Mtl_strstr(lpszSrc, lpszSub);

	// return -1 for not found, distance from beginning otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - lpszSrc);	
}

inline int __MtlFind(const CString& str, int nStart, const CString& strFind)
{
	CString strText = str.Right(str.GetLength() - nStart);
	int nIndex = strText.Find(strFind);//__MtlFind(strText, strFind);
	if (nIndex == -1)
		return -1;
	else {
		return nStart + nIndex;
	}
}

inline int __MtlFindChar(const CString& str, int nStart, TCHAR ch)
{
	CString strText = str.Right(str.GetLength() - nStart);
	int nIndex = strText.Find(ch);
	if (nIndex == -1)
		return -1;
	else {
		ATLASSERT(str[nStart + nIndex] == ch);
		return nStart + nIndex;
	}
}

template <class _InputIter>
bool MtlSearchString(_InputIter __first, _InputIter __last, const CString& str)
{
	if (str.IsEmpty())
		return false;

	for ( ; __first != __last; ++__first) {
		if (str.Find(*__first) != -1)
			return true;
	}

	return false;
}

inline TCHAR Mtl_tolower(TCHAR ch)
{
	return ((ch >= _T('A') && ch <= _T('Z')) ? (ch - _T('A') + _T('a')) : ch);
}

inline bool Mtl_istalnum(TCHAR ch)
{
	return (ch >= _T('a') && ch <= _T('z')) || 
		(ch >= _T('A') && ch <= _T('Z')) || (ch >= _T('0') && ch <= _T('9'));
}

inline bool Mtl_isalpha(TCHAR ch)
{
	return (ch >= _T('a') && ch <= _T('z')) || (ch >= _T('A') && ch <= _T('Z'));
}

//Thanks to http://www.hidecnet.ne.jp/~sinzan/tips/main.htm, and you.
inline bool _StrMatchWildCard(LPCTSTR Ptn, LPCTSTR Str)
{
	switch( *Ptn )
	{
		case _T('\0'):
			return (*Str==_T('\0'));
		case _T('*'):
			return _StrMatchWildCard( Ptn+1, Str ) || (*Str!=_T('\0')) && _StrMatchWildCard( Ptn, Str+1 );
		case _T('?'):
			return (*Str!=_T('\0')) && _StrMatchWildCard( Ptn+1, Str+1 );
		default:
			return (Mtl_tolower(*Ptn) == Mtl_tolower(*Str)) && _StrMatchWildCard(Ptn + 1, Str + 1);
	}
}

template <class _InputIter>
bool MtlSearchStringWildCard(_InputIter __first, _InputIter __last, const CString& str)
{
	if (str.IsEmpty())
		return false;

	for ( ; __first != __last; ++__first) {
		CString ptn(*__first);
		if (ptn.Find(_T('*')) != -1 || ptn.Find(_T('?')) != -1) {
			if (_StrMatchWildCard(ptn, str))
				return true;
		}
		else {
			if (str == *__first) {
				ATLTRACE2(atlTraceUser, 4, _T("%s = %s\n"), *__first, str);
				return true;
			}
		}
	}

	return false;
}

inline void MtlRemoveTrailingBackSlash(CString& str)
{
	if (__MtlIsLastChar(str, _T('\\')))
		str = str.Left(str.GetLength() - 1);
/*
	int nIndex = str.ReverseFind(_T('\\'));
	if (nIndex != -1 && nIndex == str.GetLength() - 1)// trailing
		str = str.Left(str.GetLength() - 1);
*/
}

inline void MtlRemoveStringHeaderAndFooter(CString& str)
{
	if (str.GetLength() == 0)
		return;

	if (str.GetAt(0) == _T('\"') && __MtlIsLastChar(str, _T('\"')))
		str = str.Mid(1, str.GetLength() - 2);
}

inline void MtlRemoveTrailingSpace(CString& str)
{
	if (__MtlIsLastChar(str, _T(' ')))
		str = str.Left(str.GetLength() - 1);
}

inline void MtlMakeSureTrailingChar(CString& strDirectoryPath, TCHAR ch)
{
	if (!__MtlIsLastChar(strDirectoryPath, ch))
		strDirectoryPath += ch;
}

inline void MtlMakeSureTrailingBackSlash(CString& strDirectoryPath)
{
	MtlMakeSureTrailingChar(strDirectoryPath, _T('\\'));
}

inline CString MtlGetDirectoryPath(const CString& strPath, bool bAddBackSlash = false, TCHAR chSep = _T('\\'))
{
	int nIndex = strPath.ReverseFind(chSep);
	CString strRet = strPath.Left(nIndex);

	if (bAddBackSlash)
		MtlMakeSureTrailingChar(strRet, chSep);

	return strRet;
}

template <class _Function>
bool MtlForEachObject_OldShell(const CString& strDirectoryPath, _Function __f, bool bIncludeHidden = false)
{
	CString strPathFind = strDirectoryPath;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;
	HANDLE h = ::FindFirstFile(strPathFind, &wfd);
	if (h == INVALID_HANDLE_VALUE)
		return false;
		
	// Now scan the directory
	do {
		BOOL bDirectory = wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
		BOOL bVisible = bIncludeHidden ? TRUE : ((wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0);

		if (bVisible == FALSE)
			continue;

		if (bDirectory) {
			// ignore the current and parent directory entries
			if (::lstrcmp(wfd.cFileName, _T(".")) == 0 || ::lstrcmp(wfd.cFileName, _T("..")) == 0)
				continue;
				
			CString strDirectoryPath = strPath + wfd.cFileName;
			MtlMakeSureTrailingBackSlash(strDirectoryPath);
			__f(strDirectoryPath, true);
			continue;
		}
		else {
			__f(strPath + wfd.cFileName, false);
		}

	} while (::FindNextFile(h, &wfd));
	::FindClose(h);

	return true;
}

template <class _Function>
bool MtlForEachFile(const CString& strDirectoryPath, _Function __f)
{
	CString strPathFind = strDirectoryPath;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;
	HANDLE h = ::FindFirstFile(strPathFind, &wfd);
	if (h == INVALID_HANDLE_VALUE)
		return false;
		
	// Now scan the directory
	do {
		// it is a file
		if ((wfd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) == 0) {
			__f(strPath + wfd.cFileName);
		}
	} while (::FindNextFile(h, &wfd));
	::FindClose(h);

	return true;
}

inline bool MtlIsFileExist(const CString& strDirectoryPath)
{
	CString strPathFind = strDirectoryPath;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;
	HANDLE h = ::FindFirstFile(strPathFind, &wfd);
	if (h == INVALID_HANDLE_VALUE)
		return false;
	
	// Now scan the directory
	do {
		// it is a file
		if ((wfd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) == 0) {
			::FindClose(h);
			return true;
		}
	} while (::FindNextFile(h, &wfd));

	::FindClose(h);
	return false;
}

template <class _Function>
bool MtlForEachFileSort(const CString& strDirectoryPath, _Function __f)
{
	CString strPathFind = strDirectoryPath;
	CSimpleArray<CString> strings;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;
	HANDLE h = ::FindFirstFile(strPathFind, &wfd);
	if (h == INVALID_HANDLE_VALUE)
		return false;
		
	// Now scan the directory
	do {
		// it is a file
		if ((wfd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) == 0) {
			strings.Add(strPath + wfd.cFileName);
		}
	} while (::FindNextFile(h, &wfd));
	::FindClose(h);

	std::sort(_begin(strings), _end(strings));
	std::for_each(_begin(strings), _end(strings), __f);

	return true;
}

template <class _Function>
bool MtlForEachDirectory(const CString& strDirectoryPath, _Function __f)
{
	CString strPathFind = strDirectoryPath;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;
	HANDLE h = ::FindFirstFile(strPathFind, &wfd);
	if (h == INVALID_HANDLE_VALUE)
		return false;

	// check the subdirectories for more
	do {
		BOOL bDirectory = wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
		BOOL bVisible = (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0;
		if (bDirectory && bVisible) {
			// ignore the current and parent directory entries
			if (::lstrcmp(wfd.cFileName, _T(".")) == 0 || ::lstrcmp(wfd.cFileName, _T("..")) == 0)
				continue;
				
			CString strDirectoryPath = strPath + wfd.cFileName;
			MtlMakeSureTrailingBackSlash(strDirectoryPath);
			__f(strDirectoryPath);
		}
	} while (::FindNextFile(h, &wfd));
	::FindClose(h);

	return true;
}

template <class _Function>
bool MtlForEachDirectorySort(const CString& strDirectoryPath, _Function __f)
{
	CString strPathFind = strDirectoryPath;
	CSimpleArray<CString> strings;
	MtlMakeSureTrailingBackSlash(strPathFind);
	CString strPath = strPathFind;
	strPathFind += _T("*.*");

	WIN32_FIND_DATA wfd;

⌨️ 快捷键说明

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