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

📄 mtlmisc.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:
	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 + -