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

📄 itemidlist.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
	CComPtr<IEnumIDList> spEnum;
	HRESULT hr = pFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		ATLASSERT(pidl != NULL);
		CItemIDList idl; idl.Attach(pidl);
		__f(pFolder, idl);
	}

	return __f;
}

template <typename _Function>
_Function MtlForEachFolderAndFile(IShellFolder* pFolder, _Function __f, bool bIncludeHidden = false)
{
	DWORD grfFlags = bIncludeHidden ? SHCONTF_NONFOLDERS|SHCONTF_FOLDERS|SHCONTF_INCLUDEHIDDEN : SHCONTF_NONFOLDERS|SHCONTF_FOLDERS;

	CComPtr<IEnumIDList> spEnum;
	HRESULT hr = pFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		_INCREMENT_COUNT();
		ATLASSERT(pidl != NULL);
		CItemIDList idl; idl.Attach(pidl);
		__f(pFolder, idl);
	}

	return __f;
}
	*/

template <class _Function>
_Function MtlForEachObject(const CItemIDList& idlFolder, _Function __f, bool bIncludeHidden = false)
{
	// get desktop
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return __f;

	// get the folder
	CComPtr<IShellFolder> spFolder;
	hr = spDesktopFolder->BindToObject(idlFolder, NULL, IID_IShellFolder, (void**)&spFolder);
	if (FAILED(hr)) {
		CItemIDList idl;
		hr = ::SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &idl);
		if (FAILED(hr))
			return __f;

		if (idl == idlFolder)// check if same idl or not
			spFolder = spDesktopFolder;
		else	
			return __f;
	}

	DWORD grfFlags = SHCONTF_FOLDERS|SHCONTF_NONFOLDERS;
	if (bIncludeHidden)
		grfFlags |= SHCONTF_INCLUDEHIDDEN;

	CComPtr<IEnumIDList> spEnum;
	hr = spFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		_INCREMENT_COUNT();
		ATLASSERT(pidl != NULL);

		CItemIDList idlFile; idlFile.Attach(pidl);

		ULONG dwAttributes =  SFGAO_FOLDER;
		LPCITEMIDLIST pidls[] = { idlFile.m_pidl };
		HRESULT hr = spFolder->GetAttributesOf(1, pidls, &dwAttributes);
		if (FAILED(hr))
			continue;

		bool bFolder = _check_flag(SFGAO_FOLDER, dwAttributes);// check
		__f(spFolder, idlFolder, idlFile, bFolder);
	}

	return __f;
}

template <class _Function>
_Function MtlForEachFolder(const CItemIDList& idlFolder, _Function __f, bool bIncludeHidden = false)
{
	// get desktop
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return __f;

	// get the folder
	CComPtr<IShellFolder> spFolder;
	hr = spDesktopFolder->BindToObject(idlFolder, NULL, IID_IShellFolder, (void**)&spFolder);
	if (FAILED(hr))
		return __f;

	DWORD grfFlags = bIncludeHidden ? SHCONTF_FOLDERS|SHCONTF_INCLUDEHIDDEN : SHCONTF_FOLDERS;

	CComPtr<IEnumIDList> spEnum;
	hr = spFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		_INCREMENT_COUNT();
		ATLASSERT(pidl != NULL);

		CItemIDList idlFile; idlFile.Attach(pidl);

		ULONG dwAttributes = SFGAO_FOLDER;
		LPCITEMIDLIST pidls[] = { idlFile.m_pidl };
		spFolder->GetAttributesOf(1, pidls, &dwAttributes);
		if (dwAttributes & SFGAO_FOLDER)	// required
			__f(spFolder, idlFolder, idlFile);
	}

	return __f;
}

template <class _Function>
_Function MtlForEachFile(const CItemIDList& idlFolder, _Function __f, bool bIncludeHidden = false)
{
	// get desktop
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return __f;

	// get the folder
	CComPtr<IShellFolder> spFolder;
	hr = spDesktopFolder->BindToObject(idlFolder, NULL, IID_IShellFolder, (void**)&spFolder);
	if (FAILED(hr))
		return __f;

	DWORD grfFlags = bIncludeHidden ? SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN : SHCONTF_NONFOLDERS;

	CComPtr<IEnumIDList> spEnum;
	hr = spFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		_INCREMENT_COUNT();
		ATLASSERT(pidl != NULL);

		CItemIDList idlFile; idlFile.Attach(pidl);

		ULONG dwAttributes = SFGAO_FOLDER;
		LPCITEMIDLIST pidls[] = { idlFile.m_pidl };
		spFolder->GetAttributesOf(1, pidls, &dwAttributes);
		if (!(dwAttributes & SFGAO_FOLDER))	// required
			__f(spFolder, idlFolder, idlFile);
	}

	return __f;
}

inline bool MtlGetDisplayName(IShellFolder* pFolder, LPCITEMIDLIST lpi,
							  CString& rString, DWORD uFlags = SHGDN_NORMAL)
{
	ATLASSERT(pFolder != NULL);
	ATLASSERT(lpi != NULL);

	STRRET str;
	HRESULT hr = pFolder->GetDisplayNameOf(lpi, uFlags, &str);
	if (FAILED(hr))
		return false;

	USES_CONVERSION;
	switch (str.uType) {
	case STRRET_WSTR:
		rString = W2T(str.pOleStr);
		break;

	case STRRET_OFFSET:
		rString = (LPSTR)lpi + str.uOffset;
		break;

	case STRRET_CSTR:             
		rString = (LPSTR)str.cStr;
		break;
	
	default:
		 return false;
	}

	return true;
}
/*
inline CString MtlGetDisplayName(const CString& strFullPath)
{
	CComPtr<IShellFolder> spDesktop;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktop);
	if (FAILED(hr))
		return CString();

	CString strName;
	if (!MtlGetDisplayName(spDesktop, CItemIDList(strFullPath), strName))
		return CString();

	return strName;
}
*/
inline CString MtlGetDisplayName(LPCITEMIDLIST pidlRelative)
{// The desktop folder can give a name to you even if a relative idl
	if (pidlRelative == NULL)
		return CString();

	CComPtr<IShellFolder> spDesktop;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktop);
	if (FAILED(hr))
		return CString();

	CString strName;
	if (!MtlGetDisplayName(spDesktop, pidlRelative, strName))
		return CString();

	return strName;
}

inline CItemIDList MtlSetDisplayName(IShellFolder* pFolder, LPCITEMIDLIST pidl,
									 LPCTSTR lpszName, HWND hWnd, DWORD uFlags = SHGDN_NORMAL)
{
	CItemIDList idl;
	USES_CONVERSION;
	HRESULT hr = pFolder->SetNameOf(hWnd, pidl, T2COLE(lpszName), uFlags, &idl);
	if (SUCCEEDED(hr))
		return idl;

	return idl;
}
/*
inline bool MtlGetDisplayName(CString& strName, const CString& strFolder, const CString& strObject)
{
	CItemIDList idlFolder = strFolder;
	CItemIDList idl = strObject;
	idl -= idlFolder;

	if (idl.IsNull())
		return false;

	CComPtr<IShellFolder> spDesktop;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktop);
	if (FAILED(hr))
		return false;

	CComPtr<IShellFolder> spFolder;
	HRESULT hr = spDesktopFolder->BindToObject(idlFolder, NULL, IID_IShellFolder, (void**)&spFolder);
	if (FAILED(hr))
		return false;

	return MtlGetDisplayName(spFolder, idl, strName);
}
*/
bool MtlGetShellFolder(LPCITEMIDLIST pidl, IShellFolder** ppFolder)
{
	ATLASSERT(pidl != NULL);

	CComPtr<IShellFolder> spDesktop;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktop);
	if (FAILED(hr))
		return false;

	hr = spDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)ppFolder);
	if (FAILED(hr))
		return false;

	return true;
}

// Note. It would fail if not the ordinary path.
inline CItemIDList MtlGetFullItemIDList(IShellFolder* pFolder, LPCITEMIDLIST lpi)
{
	CString strName;
	if (!MtlGetDisplayName(pFolder, lpi, strName, SHGDN_FORPARSING))
		return CItemIDList();

	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return CItemIDList();

	ULONG chEaten;
	CItemIDList idlFolder;
	USES_CONVERSION;
	hr = spDesktopFolder->ParseDisplayName(NULL, NULL, T2OLE((LPTSTR)(LPCTSTR)strName),
			&chEaten, &idlFolder, NULL);
	if (FAILED(hr))
		return CItemIDList();

	return idlFolder;
}

inline int MtlGetSystemIconIndex(LPCITEMIDLIST lpi, UINT uFlags = SHGFI_SMALLICON)
{
	ATLASSERT(lpi != NULL);

	uFlags |= SHGFI_PIDL | SHGFI_SYSICONINDEX;
				
	SHFILEINFO sfi;   
	DWORD dwResult = ::SHGetFileInfo((LPCTSTR)lpi, 0, &sfi, sizeof(SHFILEINFO), uFlags);
	if (dwResult == 0)
		return -1;

	return sfi.iIcon;
}


inline bool MtlGetAttributesOf(LPCITEMIDLIST pidlFull, ULONG& dwAttributes)
{
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return false;

	LPCITEMIDLIST pidls[] = { pidlFull };
	hr = spDesktopFolder->GetAttributesOf(1, pidls, &dwAttributes);
	if (FAILED(hr))
		return false;

	return true;
}

// Note. It is possible to make browsing slow.
inline bool MtlHasSubObject(const CItemIDList& idlFolder, bool bIncludeHidden = false)
{
	ATLASSERT(idlFolder.m_pidl != NULL);
	// get desktop
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return false;

	// get the folder
	CComPtr<IShellFolder> spFolder;
	hr = spDesktopFolder->BindToObject(idlFolder, NULL, IID_IShellFolder, (void**)&spFolder);
	if (FAILED(hr))
		return false;

	DWORD grfFlags = bIncludeHidden ? SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN : SHCONTF_FOLDERS|SHCONTF_NONFOLDERS;

	CComPtr<IEnumIDList> spEnum;
	hr = spFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return false;

	LPITEMIDLIST pidl;
	ULONG celtFetched;
	while (spEnum->Next(1, &pidl, &celtFetched) == S_OK) {
		ATLASSERT(pidl != NULL);
		CItemIDList idl; idl.Attach(pidl);
		return true;
	}

	return false;
}

// Note. this is still not precise.
inline bool MtlIsRealFolder(const CItemIDList& idlFolder)
{
	ATLASSERT(idlFolder.m_pidl != NULL);
	// get desktop
	CComPtr<IShellFolder> spDesktopFolder;
	HRESULT hr = ::SHGetDesktopFolder(&spDesktopFolder);
	if (FAILED(hr))
		return false;

	ULONG dwAttributes = SFGAO_FOLDER;
	LPCITEMIDLIST pidls[] = { idlFolder.m_pidl };
	hr = spDesktopFolder->GetAttributesOf(1, pidls, &dwAttributes);
	if (dwAttributes & SFGAO_FOLDER)
		return true;
	else
		return false;
}

bool MtlShellExecute(HWND hWnd, LPCITEMIDLIST pidl)
{
	ATLASSERT(pidl != NULL);

	SHELLEXECUTEINFO sei = {
		sizeof(SHELLEXECUTEINFO), SEE_MASK_INVOKEIDLIST,
		hWnd,
		_T(""), _T(""), _T(""),	_T(""),
		SW_SHOWNORMAL, _Module.GetModuleInstance(),
		(LPVOID)pidl,
		NULL, 0, 0, NULL
	};

	return ShellExecuteEx(&sei) == TRUE;
}

inline bool MtlIsTooSlowIDList(LPCITEMIDLIST pidl)
{
	TCHAR szPath[MAX_PATH]; szPath[0] = _T('\0');
	::SHGetPathFromIDList(pidl, szPath);
	CString strExt = CString(szPath).Right(4);
	return (strExt.CompareNoCase(_T(".url")) == 0);
}

/*
template <typename _OutputIter>
bool MtlEnumFile(IShellFolder* pFolder, _OutputIter __result, bool bIncludeHidden = false)
{
  *__result = *__first;
  while (++__first != __last)
    if (!(*__result == *__first))
      *++__result = *__first;
  return ++__result;

	DWORD grfFlags = bIncludeHidden ? SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN : SHCONTF_NONFOLDERS;

	CComPtr<IEnumIDList> spEnum;
	HRESULT hr = pFolder->EnumObjects(NULL, grfFlags, &spEnum);
	if (FAILED(hr))
		return __f;

	typedef enum_iterator<IEnumIDList, &IID_IEnumIDList, LPITEMIDLIST> pidl_itor;
	for (pidl_itor it = pidl_itor(spEnum, 64); it != pidl_itor(); ++it) {
		CItemIDList idl; idl.Attach(*it);
		__f(pFolder, idl);
	}

	return __f;
}
*/

⌨️ 快捷键说明

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