我用下面这些代码模仿了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);
                                                        }   
                                                }   
                                        }        

解决方案 »

  1.   

    “我的电脑”这种虚拟文件夹不是用路径来标识的,用ITEMIDLIST吧
      

  2.   

    另外,这个函数需要一个CSIDL的参数,我在这个循环中要从哪里得到这个参数呢?
      

  3.   

    还有一个问题是。我在程序中的这一句if (std::wstring(_T("我的电脑")) == fileinfoTest.szDisplayName)十分勉强。一旦用户换了“我的电脑”的名字,我的程序就没法得到逻辑硬盘了
      

  4.   

    楼主说的这些没有完整路径,没有文件文件夹那样的文件路径。不过它们是由层次关系的。
    桌面,我的电脑,控制面板这些都是名字域空间,根节点是桌面,我的电脑,网上邻居等是桌面的子空间。
    他们的关系可以通过类似路径的GUID来表示。
    比如:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{********-****-****-****-************}表示我的电脑下面的一个什么空间。网上邻居,控制面板都可以这么表示。