ファイル名やフォルダ名などの文字列からIDLを取得する方法にはいくつかある。
ここでは
ILCreateFromPath、SHSimpleIDListFromPath、IShellFolderを利用する3つの方法で順番に取得を試みている。ILCreateFromPathやSHSimpleIDListFromPathだけでは取得できない場合でもこの3つを併用すると確実に取得できる。
#include "atlstr.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;
#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,&nAttribute);
}
#endif
pIShellFolder->Release();
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);
}
