通配符和IShellFolder枚举?

通配符和IShellFolder枚举?,shell,winapi,com,Shell,Winapi,Com,我想尝试从FindFirstFile()/FindNextFile()移动,直接使用IShellFolder获取文件列表。原因是我想通过SHNCreateItemFromIDList()为每个文件获取一个IShellItem,并获得传递给函数所需的一切。如果我使用文件路径函数,我想每次在传递到SHCreateItemFromParsingName()之前都需要构建完整路径,但我会问另一个与此相关的问题 我这里的问题仅限于使用IShellFolder枚举使用通配符的文件和文件夹。是否有内置的功能来

我想尝试从
FindFirstFile()
/
FindNextFile()
移动,直接使用
IShellFolder
获取文件列表。原因是我想通过
SHNCreateItemFromIDList()
为每个文件获取一个
IShellItem
,并获得传递给函数所需的一切。如果我使用文件路径函数,我想每次在传递到
SHCreateItemFromParsingName()
之前都需要构建完整路径,但我会问另一个与此相关的问题

我这里的问题仅限于使用
IShellFolder
枚举使用通配符的文件和文件夹。是否有内置的功能来实现这一点,或者您必须自己进行文件匹配


蒂娅

shell API提供枚举,但没有任何类似于
FindFirstFile()
/
FindNextFile()
的过滤或通配符功能


因此,在使用shell枚举功能时,必须手动筛选项

不能使用IShellFolder进行筛选,但可以使用Shell中内置的搜索功能以编程方式执行相同的操作,就像使用Windows资源管理器UI一样

例如,您可以在右角的搜索框中键入类似ext:.txt的内容,这意味着您要筛选扩展名为.txt的所有文件:

这是一些C++示例代码,有些等价(我已经删除了每一行的错误检查,但是确保您测试所有可能的错误):

intmain()
{
共初始化(空);
{
计算机检索;
采购项目;
采购项目;
采购经理;
CComPtr解析器;
CComPtr溶液;
买方条件;
CComPtr搜索项;
会计科目;
//创建搜索文件夹工厂
search.CoCreateInstance(CLSID_SearchFolderItemFactory);
//创建d:\temp shell项并将搜索文件夹范围设置为它
SHCreateItemFromParsingName(L“d:\\temp”,NULL,IID_PPV_参数(&item));
SHCreateShellItemArrayFromShellItem(item,IID_PPV_参数(&items));
搜索->设置范围(项目);
//创建查询解析器管理器
经理CoCreateInstance(CLSID_QueryParserManager);
mgr->CreateLoadedParser(L“”,0,IID_PPV_参数(&parser));
//解析ms搜索表达式
解析器->解析(L“ext:.txt”、NULL和solution);
//获取解析器为我们构建的条件
解决方案->获取查询(&C)条件,空;
//将条件提供给搜索文件夹工厂
搜索->设置条件(条件);
//将搜索结果作为shell项(虚拟文件夹)返回并枚举它
搜索->GetShellItem(IID_PPV_参数(&searchItem));
searchItem->BindToHandler(NULL、BHID_EnumItems、IID_PPV_参数(&EnumItems));
做
{
幼儿;
乌龙取回;
HRESULT hr2=enumItems->Next(1,&子项,&获取);
如果(!已获取)
打破
//获取显示名称(例如)
CCOMHEAPTR名称;
child->GetDisplayName(SIGDN\u NORMALDISPLAY,&name);
wprintf(L“项目:%s\n”,名称);
ccomheaptr路径;
child->GetDisplayName(SIGDN_FILESYSPATH,&path);
wprintf(L“路径:%s\n”,路径);
}虽然(正确);
}
coninitialize();
返回0;
}

搜索ms语言非常强大。其语法在此处可用:

IShellFolder
枚举不支持通配符。您必须手动筛选子项谢谢,我在一些其他内容的示例中看到了有关ISearchFolderItemFactory的内容。但很高兴在这里详细记录了如何做到这一点。尽管如此,它看起来确实像是原始的许多步骤/工作,没有一个简单易用的类。
int main()
{
  CoInitialize(NULL);
  {
    CComPtr<ISearchFolderItemFactory> search;
    CComPtr<IShellItem> item;
    CComPtr<IShellItemArray> items;
    CComPtr<IQueryParserManager> mgr;
    CComPtr<IQueryParser> parser;
    CComPtr<IQuerySolution> solution;
    CComPtr<ICondition> condition;
    CComPtr<IShellItem> searchItem;
    CComPtr<IEnumShellItems> enumItems;

    // create search folder factory
    search.CoCreateInstance(CLSID_SearchFolderItemFactory);

    // create d:\temp shell item and set search folder scope to it
    SHCreateItemFromParsingName(L"d:\\temp", NULL, IID_PPV_ARGS(&item));
    SHCreateShellItemArrayFromShellItem(item, IID_PPV_ARGS(&items));
    search->SetScope(items);

    // create the query parser manager
    mgr.CoCreateInstance(CLSID_QueryParserManager);
    mgr->CreateLoadedParser(L"", 0, IID_PPV_ARGS(&parser));

    // parse an ms-search expression
    parser->Parse(L"ext:.txt", NULL, &solution);

    // get the condition the parser has built for us
    solution->GetQuery(&condition, NULL);

    // give the condition to the search folder factory
    search->SetCondition(condition);

    // get the search result back as a shell item (a virtual folder) and enumerates it
    search->GetShellItem(IID_PPV_ARGS(&searchItem));
    searchItem->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&enumItems));

    do
    {
      CComPtr<IShellItem> child;
      ULONG fetched;
      HRESULT hr2 = enumItems->Next(1, &child, &fetched);
      if (!fetched)
        break;

      // get the display name (for example)
      CComHeapPtr<WCHAR> name;
      child->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
      wprintf(L"item: %s\n", name);

      CComHeapPtr<WCHAR> path;
      child->GetDisplayName(SIGDN_FILESYSPATH, &path);
      wprintf(L" path: %s\n", path);
    } while (TRUE);
  }
  CoUninitialize();
  return 0;
}