我用下面这些代码模仿了windows资源浏览器中的地址栏。但是不知道应该如何保存每个项目的完整路径。比如桌面,硬盘分区等,用SHGetPathFromIDList得到的都是空字符串。请问如何得到这些特殊文件夹的完整路径? if (SUCCEEDED(SHGetDesktopFolder(&psfTop))) //Get IShellFold interface.
{
if (SUCCEEDED(psfTop->EnumObjects(m_ComboBoxEx.m_hWnd, //EnumObjects and get enumidlist.
SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN | SHCONTF_INIT_ON_FIRST_NEXT | SHCONTF_NONFOLDERS,
&IDListRoot)))
{
if (IDListRoot!=NULL)
{
//while (SUCCEEDED(IDListRoot->Next(iCycle,&IDListNext,NULL))) while ((IDListRoot->Next(0,&IDListNext,&celtFetched)) == S_OK && (celtFetched) == 1) //Get itemidlist.
{ SHGetFileInfo((LPCTSTR)IDListNext,
FILE_ATTRIBUTE_NORMAL,
&fileinfoTest,sizeof(SHFILEINFO),
SHGFI_PIDL | SHGFI_SYSICONINDEX |
SHGFI_SMALLICON | SHGFI_DISPLAYNAME |
SHGFI_USEFILEATTRIBUTES | SHGFI_ATTRIBUTES | SHGFI_ICON| SHGFI_TYPENAME|SHGFI_SMALLICON);
//获取路径
TCHAR fullPath[MAX_PATH];
ZeroMemory(&fullPath,MAX_PATH);
SHGetPathFromIDList(IDListNext,fullPath);
//这里的对话框在现实特殊文件夹的时候总为空
AfxMessageBox(fullPath);
//获取完毕
//插入listitem if (fileinfoTest.dwAttributes & SFGAO_FOLDER)
{
//如果是文件夹
COMBOBOXEXITEM a;
ZeroMemory(&a,sizeof(COMBOBOXEXITEM));
a.pszText =fileinfoTest.szDisplayName;
a.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT;
a.iImage = fileinfoTest.iIcon;
a.iSelectedImage = fileinfoTest.iIcon;
a.lParam = (LPARAM)IDListNext;
a.iItem = index++;
a.iIndent = 1;
a.lParam = (LPARAM)IDListNext;
m_ComboBoxEx.InsertItem(&a);
//只得到“我的电脑”下的节点,其他桌面上的目录的二级节点不感兴趣
if (std::wstring(_T("我的电脑")) == fileinfoTest.szDisplayName)
{
HRESULT hr = psfTop->BindToObject(IDListNext,
NULL,IID_IShellFolder,
(LPVOID *)&psfSon);
//pMalloc->Free(IDListNext); HRESULT ht = psfSon->EnumObjects(m_ComboBoxEx.m_hWnd, //Enum son Objects and get enumidlist.
SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN ,
&IDListRootNext); LPITEMIDLIST pidlAbs;
while (IDListRootNext->Next(1,&IDListSonNext,NULL) != S_FALSE)
{
pidlAbs = ILCombine(IDListNext, IDListSonNext);
SHGetFileInfo((LPCTSTR)pidlAbs,
FILE_ATTRIBUTE_NORMAL,
&fileinfoSon,sizeof(SHFILEINFO),
SHGFI_PIDL | SHGFI_SYSICONINDEX |
SHGFI_SMALLICON | SHGFI_DISPLAYNAME |
SHGFI_USEFILEATTRIBUTES | SHGFI_ATTRIBUTES | SHGFI_ICON| SHGFI_TYPENAME|SHGFI_SMALLICON);
ZeroMemory(&a,sizeof(COMBOBOXEXITEM));
a.pszText =fileinfoSon.szDisplayName;
a.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT;
a.iImage = fileinfoSon.iIcon;
a.iSelectedImage = fileinfoSon.iIcon;
a.lParam = (LPARAM)IDListNext;
a.iItem = index++;
a.iIndent = 2;
m_ComboBoxEx.InsertItem(&a);
}
}
}
{
if (SUCCEEDED(psfTop->EnumObjects(m_ComboBoxEx.m_hWnd, //EnumObjects and get enumidlist.
SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN | SHCONTF_INIT_ON_FIRST_NEXT | SHCONTF_NONFOLDERS,
&IDListRoot)))
{
if (IDListRoot!=NULL)
{
//while (SUCCEEDED(IDListRoot->Next(iCycle,&IDListNext,NULL))) while ((IDListRoot->Next(0,&IDListNext,&celtFetched)) == S_OK && (celtFetched) == 1) //Get itemidlist.
{ SHGetFileInfo((LPCTSTR)IDListNext,
FILE_ATTRIBUTE_NORMAL,
&fileinfoTest,sizeof(SHFILEINFO),
SHGFI_PIDL | SHGFI_SYSICONINDEX |
SHGFI_SMALLICON | SHGFI_DISPLAYNAME |
SHGFI_USEFILEATTRIBUTES | SHGFI_ATTRIBUTES | SHGFI_ICON| SHGFI_TYPENAME|SHGFI_SMALLICON);
//获取路径
TCHAR fullPath[MAX_PATH];
ZeroMemory(&fullPath,MAX_PATH);
SHGetPathFromIDList(IDListNext,fullPath);
//这里的对话框在现实特殊文件夹的时候总为空
AfxMessageBox(fullPath);
//获取完毕
//插入listitem if (fileinfoTest.dwAttributes & SFGAO_FOLDER)
{
//如果是文件夹
COMBOBOXEXITEM a;
ZeroMemory(&a,sizeof(COMBOBOXEXITEM));
a.pszText =fileinfoTest.szDisplayName;
a.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT;
a.iImage = fileinfoTest.iIcon;
a.iSelectedImage = fileinfoTest.iIcon;
a.lParam = (LPARAM)IDListNext;
a.iItem = index++;
a.iIndent = 1;
a.lParam = (LPARAM)IDListNext;
m_ComboBoxEx.InsertItem(&a);
//只得到“我的电脑”下的节点,其他桌面上的目录的二级节点不感兴趣
if (std::wstring(_T("我的电脑")) == fileinfoTest.szDisplayName)
{
HRESULT hr = psfTop->BindToObject(IDListNext,
NULL,IID_IShellFolder,
(LPVOID *)&psfSon);
//pMalloc->Free(IDListNext); HRESULT ht = psfSon->EnumObjects(m_ComboBoxEx.m_hWnd, //Enum son Objects and get enumidlist.
SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN ,
&IDListRootNext); LPITEMIDLIST pidlAbs;
while (IDListRootNext->Next(1,&IDListSonNext,NULL) != S_FALSE)
{
pidlAbs = ILCombine(IDListNext, IDListSonNext);
SHGetFileInfo((LPCTSTR)pidlAbs,
FILE_ATTRIBUTE_NORMAL,
&fileinfoSon,sizeof(SHFILEINFO),
SHGFI_PIDL | SHGFI_SYSICONINDEX |
SHGFI_SMALLICON | SHGFI_DISPLAYNAME |
SHGFI_USEFILEATTRIBUTES | SHGFI_ATTRIBUTES | SHGFI_ICON| SHGFI_TYPENAME|SHGFI_SMALLICON);
ZeroMemory(&a,sizeof(COMBOBOXEXITEM));
a.pszText =fileinfoSon.szDisplayName;
a.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT;
a.iImage = fileinfoSon.iIcon;
a.iSelectedImage = fileinfoSon.iIcon;
a.lParam = (LPARAM)IDListNext;
a.iItem = index++;
a.iIndent = 2;
m_ComboBoxEx.InsertItem(&a);
}
}
}
桌面,我的电脑,控制面板这些都是名字域空间,根节点是桌面,我的电脑,网上邻居等是桌面的子空间。
他们的关系可以通过类似路径的GUID来表示。
比如:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{********-****-****-****-************}表示我的电脑下面的一个什么空间。网上邻居,控制面板都可以这么表示。