📄 mtlmisc.h
字号:
#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 + -