ファイル名やフォルダ名などの文字列からIDLを取得する方法にはいくつかある。
ここでは
ILCreateFromPath、SHSimpleIDListFromPath、IShellFolderを利用する3つの方法で順番に取得を試みている。ILCreateFromPathやSHSimpleIDListFromPathだけでは取得できない場合でもこの3つを併用すると確実に取得できる。
#include "atlstr.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;
}
void Test(void)
{
bool ret;
LPITEMIDLIST pidl;
ret = GetItemIdListFromPath(_T("c:\\autoexec.bat"),&pidl);
if(ret)
::MessageBox(NULL,_T("取得に成功しました"),_T(""),MB_OK);
else
::MessageBox(NULL,_T("失敗しました"),_T(""),MB_OK);
if(ret)
::ILFree(pidl);
}
