【问题标题】:How to Filter IShellFolder::EnumObjects result如何过滤 IShellFolder::EnumObjects 结果
【发布时间】:2012-06-10 06:51:42
【问题描述】:

我正在尝试创建一个 shell 树控件。我不希望从IShellFilder::EnumObjects 调用返回的所有项目都显示在树上,因为我需要过滤诸如回收站和控制面板之类的项目。

我的代码如下所示:

IShellFolder* pDesktopFolder=NULL;
SHGetDesktopFolder(&pDesktopFolder);


LPITEMIDLIST pidlParent=NULL;
IShellFolder* pParentFolder = NULL;
pDesktopFolder->BindToObject(pidlParent,NULL, IID_IShellFolder, (LPVOID*)&pParentFolder);

IEnumIDList* pEnumIDList = NULL;
    SHCONTF SHFlag=NULL;
    SHFlag=SHCONTF_FOLDERS | SHCONTF_INIT_ON_FIRST_NEXT | SHCONTF_NONFOLDERS  | SHCONTF_INCLUDEHIDDEN;

HRESULT hr= pParentFolder->EnumObjects(NULL, SHFlag, &pEnumIDList);

if (NOERROR == hr)
{
     LPITEMIDLIST pidl = NULL, pidlAbs;
     CString csFileType;
     HTREEITEM hItem=NULL;
     while (NOERROR == pEnumIDList->Next(1, &pidl, NULL))
     {
        //Filter out control panel, recycle bin items and other non usable items
     }
}

我不想获取每个项目的显示名称并对其进行字符串比较,因为名称可能会根据操作系统语言而改变。

可以根据每个item的CLSID进行过滤吗?最好的方法是什么?

【问题讨论】:

    标签: c++ visual-c++ windows-shell


    【解决方案1】:

    当您有 IShellFolder 和子 pidl 时,您可以使用 SHGetDataFromIDList(...,SHGDFIL_DESCRIPTIONID) 获取 pidl 目标的 CLSID。

    另见:

    【讨论】:

      【解决方案2】:

      如果你只想拥有真正的文件系统项目(就像BrowseForFolder),那么你可以使用GetAttributesOf(..)并检查SFGAO_FILESYSANCESTOR,如果它没有属性,它不是文件系统项目..(压缩文件、控制面板、回收站没有该属性)

      【讨论】:

      • Hmm.. 发现,zipfile 没有被过滤(奇怪).. 你也必须检查 SFGAO_BROWSABLE 上的 zipfile(所以如果它是 SFGA_FILESYSANCESTORSFGA_BROWSABLE 和甚至可能检查SFGA_FILESYSTEM。检查SFGA_STREAM 不是一个好主意,因为在我的系统上,“计算机”和特定驱动器下的所有文件夹似乎都已设置(Windows 7 x64 终极版)。
      • 哦,亲爱的,刚刚在 Windows XP 上发现SFGA_BROWSABLE 可以是文件夹的有效属性,并且不显示 zipfiles..grrrrr.. 这真的很烦人,下次 MS 怎么样确保一切在所有平台上都一样工作......所以压缩文件(或 .cab 文件),回到绘图板......
      【解决方案3】:

      已解决:

      我做了这个并且它的工作,但我需要看看我在哪里可以获得其他文件夹的 GUID 列表:

      ULONG nEaten=0;
          LPITEMIDLIST PidlCPanel;
          ULONG nCPAttrib = 0;
          HRESULT hr = pFolder->ParseDisplayName(NULL, NULL, _T("::{26EE0668-A00A-44D7-9371-BEB064C98683}"), &nEaten, &PidlCPanel, &nCPAttrib);
          BOOL bRes = ILIsEqual(pidl, PidlCPanel);
      

      【讨论】:

      • 您不应该使用这样的系统文件夹 GUID。使用SHGetFolderLocation() 和/或SHGetKnownFolderIDList() 函数获取系统文件夹的ITEMIDLISTs,包括回收站(CSIDL_BITBUCKET/FOLDERID_RecycleBinFolder)和控制面板(CSIDL_CONTROLS/FOLDERID_ControlPanelFolder)。跨度>
      • 你能发布一个关于如何在我的代码上下文中使用这些的答案
      • 还要记住 SHGetKnownFolderIDList 不适用于 XP。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2019-05-15
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多