ファイルやフォルダのプロパティを表示する

test96.gif
SHMultiFilePropertiesを利用するとファイルやフォルダなどのプロパティを表示できる。複数のファイルなどを選択した場合でも使える。

依存環境:ATL
#include "atlstr.h"
#include "atlcoll.h"

#include "shlobj.h"


/*!
 * \brief
 * パスからPIDLを取得する
 * 
 * 取得したPIDLは必ず CoTaskMemFree、ILFree、IMalloc::Free() のいずれかで解放すること!
 * 
 * \param[in]	pszPath
 * PIDLを取得したいパス
 * 
 * \param[out]	ppItemIdList
 * 取得したPIDL
 * 
 * \retval	true	成功
 * \retval	false	失敗
 * 
 */
bool	GetItemIdListFromPath(LPCTSTR pszPath,LPITEMIDLIST* ppItemIdList)
{
	if(ppItemIdList == NULL || pszPath == NULL || *pszPath == NULL)
		return	false;

	//ILCreateFromPathで取得
	*ppItemIdList = ::ILCreateFromPath(pszPath);
	if(*ppItemIdList)
		return	true;		//取得成功

	//SHSimpleIDListFromPathで取得
	*ppItemIdList = ::SHSimpleIDListFromPath((CAtlStringW)pszPath);
	if(*ppItemIdList)
		return	true;		//取得成功

	//IShellFolderで取得
	{
		CComPtr<IShellFolder>	pIShellFolder;
		HRESULT			hr;

		hr = ::SHGetDesktopFolder(&pIShellFolder);
		if(pIShellFolder == NULL)
			return	false;

	#ifdef	UNICODE
		hr = pIShellFolder->ParseDisplayName(NULL,NULL,pszPath,NULL,&pItemIdList,NULL);
	#else
		{
			CAtlStringW	ustrPath;

			//簡単にUnicode変換
			ustrPath = pszPath;
			hr = pIShellFolder->ParseDisplayName(NULL,NULL,ustrPath.GetBuffer(0),NULL,ppItemIdList,NULL);
		}
	#endif

		if(SUCCEEDED(hr))
			return	true;		//取得成功
	}

	return	false;
}



//
//	ファイルやフォルダのプロパティを表示する
//
bool	ShowPropertyDialog(LPCTSTR pszPath)
{
	HRESULT			hr;
	bool			ret;
	LPITEMIDLIST	pItemIdList;
	CComPtr<IShellFolder>	pIShellFolder;
	CComPtr<IDataObject>	pIDataObject;

	hr = ::SHGetDesktopFolder(&pIShellFolder);
	if(FAILED(hr))
		return	false;

	ret = GetItemIdListFromPath(pszPath,&pItemIdList);
	if(ret == false)
		return	false;

	hr = pIShellFolder->GetUIObjectOf(NULL,1,(LPCITEMIDLIST*)&pItemIdList,IID_IDataObject,NULL,(void**)&pIDataObject);
	::ILFree(pItemIdList);
	if(FAILED(hr))
		return	false;

	hr = ::SHMultiFileProperties(pIDataObject,0);

	return	SUCCEEDED(hr) ? true : false;
}





//
//	複数のファイルやフォルダのプロパティを表示する
//
bool	ShowMultiPropertyDialog(const CAtlArray<CAtlString>& astrPath)
{
	HRESULT		hr;
	CComPtr<IShellFolder>	pIShellFolder;
	CComPtr<IDataObject>	pIDataObject;

	hr = ::SHGetDesktopFolder(&pIShellFolder);
	if(FAILED(hr))
		return	false;

	//複数ファイルのPIDLを取得し、IDataObjectに結びつける
	{
		size_t	i;
		size_t	nSize;
		bool	ret;
		LPITEMIDLIST*	ppItemIdList;

		nSize = astrPath.GetCount();
		ppItemIdList = new LPITEMIDLIST[nSize];
		if(ppItemIdList == NULL)
			return	false;

		for(i = 0; i < nSize; i++)
		{
			ret = GetItemIdListFromPath(astrPath[i],&ppItemIdList[i]);
			if(ret == false)
				break;
		}

		if(ret == false)
			nSize = i;

		if(ret)
			hr = pIShellFolder->GetUIObjectOf(NULL,(UINT)nSize,(LPCITEMIDLIST*)ppItemIdList,IID_IDataObject,NULL,(void**)&pIDataObject);

		for(i = 0; i < nSize; i++)
			::ILFree(ppItemIdList[i]);
		delete	ppItemIdList;

		if(ret == false || FAILED(hr))
			return	false;
	}


	//この関数を複数のファイルのプロパティを表示できるように改造する場合は
	//以下のコメントアウト処理をSHMultiFilePropertiesの前に実行する(KB330040)
	{
		LPITEMIDLIST	pItemIdList;
		IDataObject*	pIDataObject;
	
		hr = ::SHGetSpecialFolderLocation(NULL,CSIDL_DRIVES,&pItemIdList);
		if(SUCCEEDED(hr))
		{
			hr = pIShellFolder->GetUIObjectOf(NULL,1,(LPCITEMIDLIST*)&pItemIdList,IID_IDataObject,NULL,(void**)&pIDataObject);
			::ILFree(pItemIdList);
		}
		pIDataObject->Release();
	}

	hr = ::SHMultiFileProperties(pIDataObject,0);

	return	SUCCEEDED(hr) ? true : false;
}






void	Test(void)
{
	::CoInitialize(NULL);

	//1つのファイルのプロパティ表示
	ShowPropertyDialog(_T("c:\\autoexec.bat"));

	//3つのファイルのプロパティ表示
	{
		CAtlArray<CAtlString>	astrPath;

		astrPath.Add(_T("c:\\config.sys"));
		astrPath.Add(_T("c:\\autoexec.bat"));
		astrPath.Add(_T("c:\\pagefile.sys"));
		ShowMultiPropertyDialog(astrPath);
	}

	::MessageBox(NULL,_T("ダミーメッセージボックス"),_T(""),MB_OK);

	::CoUninitialize();
}

プロジェクトファイルをダウンロード


カテゴリー「ファイル・フォルダ」 のエントリー