« ファイルやフォルダの作成や削除などを検出する | メイン | 書式文字列を使えるシェルメッセージボックスを表示する »


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

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

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

#include "shlobj.h"


//
//	パスからPIDLを取得する
//
//取得したPIDLは必ずILFreeで解放すること!
//
bool	GetItemIdListFromPath(LPCTSTR pszPath,LPITEMIDLIST* ppItemIdList)
{
	if(ppItemIdList == NULL)
		return	false;

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

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

	//IShellFolderで取得
	{
		IShellFolder*	pIShellFolder;
		HRESULT			hr;
		ULONG			nAttribute;

		hr = ::SHGetDesktopFolder(&pIShellFolder);
		if(pIShellFolder)
		{
			nAttribute = ::PathIsDirectory(pszPath) ? SFGAO_FOLDER : 0;

			{
				CAtlStringW	ustrPath;

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

			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();
}

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





クリックで再生する動画CMです