📄 mtlmisc.h
字号:
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);
strings.Add(strDirectoryPath);
}
} while (::FindNextFile(h, &wfd));
::FindClose(h);
std::sort(_begin(strings), _end(strings));
std::for_each(_begin(strings), _end(strings), __f);
return true;
}
struct _MtlEnumMDIChildStruct
{
CSimpleArray<HWND> _arrChildWnd;
HWND _hWndMDIClient;
};
template <class _Function>
_Function MtlForEachMDIChild(HWND hWndMDIClient, _Function __f)
{
_MtlEnumMDIChildStruct enumstruct;
enumstruct._hWndMDIClient = hWndMDIClient;
::EnumChildWindows(hWndMDIClient, &_MtlMDIChildEnumProc, (LPARAM)&enumstruct);
return std::for_each(_begin(enumstruct._arrChildWnd), _end(enumstruct._arrChildWnd), __f);
}
static BOOL CALLBACK _MtlMDIChildEnumProc(HWND hWnd, LPARAM lParam)
{
if (::GetWindow(hWnd, GW_OWNER))
return TRUE;
_MtlEnumMDIChildStruct* penumstruct = (_MtlEnumMDIChildStruct*)lParam;
if (::GetParent(hWnd) != penumstruct->_hWndMDIClient)
return TRUE;
penumstruct->_arrChildWnd.Add(hWnd);
return TRUE;
}
struct _MtlEnumChildren
{
CSimpleArray<HWND> _arrChildWnd;
};
template <class _Function>
_Function MtlForEachChildren(HWND hWndParent, _Function __f)
{
_MtlEnumChildren enumstruct;
::EnumChildWindows(hWndParent, &_MtlChildrenEnumProc, (LPARAM)&enumstruct);
return std::for_each(_begin(enumstruct._arrChildWnd), _end(enumstruct._arrChildWnd), __f);
}
static BOOL CALLBACK _MtlChildrenEnumProc(HWND hWnd, LPARAM lParam)
{
_MtlEnumChildren* penumstruct = (_MtlEnumChildren*)lParam;
penumstruct->_arrChildWnd.Add(hWnd);
return TRUE;
}
struct _MtlEnumChildrenCount
{
HWND _hWndParent;
int _nCount;
};
static BOOL CALLBACK _MtlChildrenCountEnumProc(HWND hWnd, LPARAM lParam)
{
_MtlEnumChildrenCount* penumstruct = (_MtlEnumChildrenCount*)lParam;
if (::GetParent(hWnd) == penumstruct->_hWndParent)
++penumstruct->_nCount;
return TRUE;
}
inline int MtlGetDirectChildrenCount(HWND hWndParent)
{
_MtlEnumChildrenCount enumstruct = { hWndParent, 0 };
::EnumChildWindows(hWndParent, &_MtlChildrenCountEnumProc, (LPARAM)&enumstruct);
return enumstruct._nCount;
}
//////////////////////////////////////////////////////////////////////////
struct _MtlEnumChildrenName
{
HWND _hWndParent;
LPCTSTR _lpszClassName;
int _nCount;
};
static BOOL CALLBACK _MtlIsDirectChildrenNameEnumProc(HWND hWnd, LPARAM lParam)
{
_MtlEnumChildrenName* penumstruct = (_MtlEnumChildrenName*)lParam;
if (::GetParent(hWnd) == penumstruct->_hWndParent) {
TCHAR sz[50];
::GetClassName(hWnd, sz, 50);
if (::lstrcmp(sz, penumstruct->_lpszClassName) == 0) {
penumstruct->_nCount++;
}
}
return TRUE;
}
inline int MtlCountDirectChildrenName(HWND hWndParent, const CString& strClassName)
{
_MtlEnumChildrenName enumstruct = { hWndParent, (LPCTSTR)strClassName, 0 };
::EnumChildWindows(hWndParent, &_MtlIsDirectChildrenNameEnumProc, (LPARAM)&enumstruct);
return enumstruct._nCount;
}
//////////////////////////////////////////////////////////////////////////
inline CString MtlGetClipboardText(bool bUseOLE = false)
{
CString strText;
if (!bUseOLE) {
if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(NULL)) {
HGLOBAL hText = ::GetClipboardData(CF_TEXT);
if (hText) {
strText = reinterpret_cast<LPSTR>(::GlobalLock(hText));
::GlobalUnlock(hText);
}
::CloseClipboard();
}
}
else {
CComPtr<IDataObject> spDataObject;
HRESULT hr = ::OleGetClipboard(&spDataObject);
if (FAILED(hr))
return strText;
FORMATETC formatetc = { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmedium;
hr = spDataObject->GetData(&formatetc, &stgmedium);
if (SUCCEEDED(hr)) {
if (stgmedium.hGlobal != NULL) {
HGLOBAL hText = stgmedium.hGlobal;
strText = reinterpret_cast<LPSTR>(::GlobalLock(hText));
::GlobalUnlock(hText);
}
::ReleaseStgMedium(&stgmedium);
}
}
return strText;
}
inline bool MtlSetClipboardText(const CString& str, HWND hWnd)
{
if (str.IsEmpty())
return false;
int nByte = str.GetLength();
HGLOBAL hText = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, nByte + 1);
if (hText == NULL)
return false;
BYTE* pText = (BYTE*)::GlobalLock(hText);
if (pText == NULL)
return false;
::memcpy(pText, (LPCTSTR)str, nByte);
::GlobalUnlock(hText);
::OpenClipboard(hWnd);
::EmptyClipboard();
::SetClipboardData(CF_TEXT, hText);
::CloseClipboard();
return true;
}
inline bool AtlCompactPathFixed(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen)
{
ATLASSERT(lpstrOut != NULL);
ATLASSERT(lpstrIn != NULL);
ATLASSERT(cchLen > 0);
LPCTSTR szEllipsis = _T("...");
const int cchEndEllipsis = 3;
const int cchMidEllipsis = 4;
if(lstrlen(lpstrIn) < cchLen) // ******changed****** I can't understand why (+1) needed.
return (lstrcpy(lpstrOut, lpstrIn) != NULL);
*lpstrOut = _T('\0'); // ******added******
// As lstrcat needs NULL-terminated string, lstrcat can't touch lpstrOut without this,
// and lpstrOut will be endless string and it may crash your program.
// check if the separator is a slash or a backslash
TCHAR chSlash = _T('\\');
for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr))
{
if((*lpstr == _T('/')) || (*lpstr == _T('\\')))
chSlash = *lpstr;
}
// find the filename portion of the path
LPCTSTR lpstrFileName = lpstrIn;
for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath))
{
if((pPath[0] == _T('\\') || pPath[0] == _T(':') || pPath[0] == _T('/'))
&& pPath[1] && pPath[1] != _T('\\') && pPath[1] != _T('/'))
lpstrFileName = pPath + 1;
}
int cchFileName = lstrlen(lpstrFileName);
// handle just the filename without a path
if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis)
{
bool bRet = (lstrcpyn(lpstrOut, lpstrIn, cchLen - cchEndEllipsis) != NULL);
if(bRet)
{
#ifndef _UNICODE
// The index that must be checked was wrong.
if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis - 1)) { // ******changed******
ATLASSERT(cchLen - cchEndEllipsis - 2 >= 0); // ******added******
lpstrOut[cchLen - cchEndEllipsis - 2] = 0; // ******changed******
}
#endif //_UNICODE
bRet = (lstrcat(lpstrOut, szEllipsis) != NULL);
}
return bRet;
}
// handle just ellipsis
if((cchLen < (cchMidEllipsis + cchEndEllipsis)))
{
for(int i = 0; i < cchLen - 1; i++)
lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T('.');
lpstrOut[i] = 0;
return true;
}
// calc how much we have to copy
int cchToCopy = cchLen - (cchMidEllipsis + cchFileName);
if(cchToCopy < 0)
cchToCopy = 0;
#ifndef _UNICODE
if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy - 1)) // ******changed******
cchToCopy--;
#endif //_UNICODE
bool bRet = (lstrcpyn(lpstrOut, lpstrIn, cchToCopy) != NULL);
if(!bRet)
return false;
// add ellipsis
bRet = (lstrcat(lpstrOut, szEllipsis) != NULL);
if(!bRet)
return false;
TCHAR szSlash[2] = { chSlash, 0 };
bRet = (lstrcat(lpstrOut, szSlash) != NULL);
if(!bRet)
return false;
// add filename (and ellipsis, if needed)
if(cchLen > (cchMidEllipsis + cchFileName))
{
bRet = (lstrcat(lpstrOut, lpstrFileName) != NULL);
}
else
{
cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis;
#ifndef _UNICODE
if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy - 1)) // ******changed******
cchToCopy--;
#endif //_UNICODE
bRet = (lstrcpyn(&lpstrOut[cchMidEllipsis], lpstrFileName, cchToCopy) != NULL);
if(bRet)
bRet = (lstrcat(lpstrOut, szEllipsis) != NULL);
}
return bRet;
}
inline bool MtlCompactPath(CString& strOut, const CString& str, int cchLen)
{
ATLASSERT(cchLen > 0);
bool bRet = AtlCompactPathFixed(strOut.GetBufferSetLength(cchLen), str, cchLen);
strOut.ReleaseBuffer();
if (!bRet || strOut.IsEmpty() || strOut == _T("..."))
return false;
return true;
}
inline CString MtlCompactString(const CString& str, int nMaxTextLength)
{
ATLASSERT(nMaxTextLength > 0);
if (str.GetLength() <= nMaxTextLength)
return str;
LPCTSTR szEllipsis = _T("...");
const int cchEndEllipsis = 3;
if (nMaxTextLength <= cchEndEllipsis) {// only ellipsis
return CString(_T('.'), nMaxTextLength);
}
int nIndex = nMaxTextLength - cchEndEllipsis;
ATLASSERT(nIndex > 0);
ATLASSERT(nIndex < str.GetLength());
if (_IsDBCSTrailByte(str, nIndex))
--nIndex;// one step back
ATLASSERT(nIndex >= 0);
return str.Left(nIndex) + szEllipsis;
}
inline void MtlRefreshBandIdealSize(CReBarCtrl rebar, CToolBarCtrl toolbar)
{
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO);
rbBand.fMask = RBBIM_IDEALSIZE;
// Calculate the size of the band
int nBtnCount = toolbar.GetButtonCount();
if(nBtnCount > 0)
{
RECT rcTmp;
BOOL bRet = (BOOL)toolbar.GetItemRect(nBtnCount-1, &rcTmp);
ATLASSERT(bRet);
rbBand.cxIdeal = rcTmp.right;
int nIndex = rebar.IdToIndex(toolbar.GetDlgCtrlID());
rebar.SetBandInfo(nIndex, &rbBand);
}
}
inline CString MtlCurrentDirectoryFileName(const CString& strFileName)
{
TCHAR sz[MAX_PATH];
::GetModuleFileName(_Module.GetModuleInstance(), sz, MAX_PATH);
CString str(sz);
int nIndex = str.ReverseFind(_T('\\'));
return str.Left(nIndex + 1) + strFileName;
}
inline CString MtlGetModuleFileName()
{
TCHAR sz[MAX_PATH];
::GetModuleFileName(_Module.GetModuleInstance(), sz, MAX_PATH);
return sz;
}
inline CString MtlGetFileNameFromCommandLine(const CString& _strCommand)
{
CString strCommand = _strCommand;
if (strCommand.Left(1) == _T("\"")) {
strCommand = strCommand.Right(strCommand.GetLength() - 1);
}
else {
return strCommand;
}
int i = strCommand.Find('"');
if (i == -1)
return _strCommand; // illegally terminated
return strCommand.Left(i);
}
inline BOOL MtlSetExcutable(const CString& strExt, const CString& strExe_, const CString& strName, bool bOn)
{
CString strExe = _T('"') + strExe_ + _T('"');// fixed by Shimawari, thanks!
CRegKey rkExt;
CRegKey rkShell;
CRegKey rkDonut;
CRegKey rkCommand;
LONG lRet;
// open ROOT
lRet = rkExt.Create(HKEY_CLASSES_ROOT, strExt);
if(lRet != ERROR_SUCCESS)
return FALSE;
if (bOn) {
// set shell value to name (means default)
lRet = rkExt.SetKeyValue(_T("shell"), strName);
if(lRet != ERROR_SUCCESS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -