通配符和 IShellFolder 枚举?
Wildcards and IShellFolder enumeration?
我想尝试离开 FindFirstFile()
/FindNextFile()
并直接使用 IShellFolder
来获取文件列表。原因是我然后想通过 SHNCreateItemFromIDList()
为每个文件获得一个 IShellItem
,并且我将拥有传递给该函数所需的一切。如果我使用文件路径函数,我想我每次都需要在传递给 SHCreateItemFromParsingName()
之前构建完整路径,但我会问另一个特定于此的问题。
我这里的问题仅限于使用IShellFolder
来枚举使用通配符的文件和文件夹。是否有内置的东西可以做到这一点,还是您必须自己进行文件匹配?
TIA!!
shell API 提供枚举,但没有类似于 FindFirstFile()
/FindNextFile()
.
的任何过滤或通配符功能
因此,在使用 shell 枚举功能时,您必须手动筛选项目。
您不能使用 IShellFolder 进行过滤,但您可以使用 Shell 中内置的搜索工具以编程方式执行相同的操作,就像使用 Windows 资源管理器 UI.
例如,您可以在右上角的搜索框中键入 ext:.txt 之类的内容,这意味着您要过滤所有带有 [=23 的文件=].txt 扩展名:
这是一些等效的 C++ 示例代码(我删除了每一行的错误检查,但请确保您测试了所有可能的错误):
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;
}
search-ms语言非常强大。其语法可在此处获得:Querying the Index with the search-ms Protocol
我想尝试离开 FindFirstFile()
/FindNextFile()
并直接使用 IShellFolder
来获取文件列表。原因是我然后想通过 SHNCreateItemFromIDList()
为每个文件获得一个 IShellItem
,并且我将拥有传递给该函数所需的一切。如果我使用文件路径函数,我想我每次都需要在传递给 SHCreateItemFromParsingName()
之前构建完整路径,但我会问另一个特定于此的问题。
我这里的问题仅限于使用IShellFolder
来枚举使用通配符的文件和文件夹。是否有内置的东西可以做到这一点,还是您必须自己进行文件匹配?
TIA!!
shell API 提供枚举,但没有类似于 FindFirstFile()
/FindNextFile()
.
因此,在使用 shell 枚举功能时,您必须手动筛选项目。
您不能使用 IShellFolder 进行过滤,但您可以使用 Shell 中内置的搜索工具以编程方式执行相同的操作,就像使用 Windows 资源管理器 UI.
例如,您可以在右上角的搜索框中键入 ext:.txt 之类的内容,这意味着您要过滤所有带有 [=23 的文件=].txt 扩展名:
这是一些等效的 C++ 示例代码(我删除了每一行的错误检查,但请确保您测试了所有可能的错误):
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;
}
search-ms语言非常强大。其语法可在此处获得:Querying the Index with the search-ms Protocol