{"id":44833,"date":"2015-01-26T07:00:00","date_gmt":"2015-01-26T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2015\/01\/26\/customizing-item-enumeration-with-ishellitem\/"},"modified":"2019-03-13T12:12:21","modified_gmt":"2019-03-13T19:12:21","slug":"20150126-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150126-00\/?p=44833","title":{"rendered":"Customizing item enumeration with IShellItem"},"content":{"rendered":"<p>If you are using the original <code>IShell&shy;Folder<\/code> interface, then <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/03\/17\/10508309.aspx\">you can use <code>SHCONTF<\/code> values to customize how child items are enumerated<\/a>. But what if you&#8217;re using <code>IShell&shy;Item<\/code>? <\/p>\n<p>Let&#8217;s take it one step at a time. First, the basic program. (Remember, Little Programs do little to no error checking.) <\/p>\n<pre>\n#define UNICODE\n#define <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/02\/12\/71851.aspx\">_UNICODE<\/a>\n#define STRICT\n#define <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/01\/24\/10387757.aspx\">STRICT_TYPED_ITEMIDS<\/a>\n#include &lt;windows.h&gt;\n#include &lt;shlobj.h&gt;\n#include &lt;atlbase.h&gt;\n#include &lt;atlalloc.h&gt;\n#include &lt;propsys.h&gt;\n#include &lt;stdio.h&gt;\n\nint __cdecl wmain(int argc, wchar_t **argv)\n{\n <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">CCoInitialize<\/a> init;\n\n if (argc &lt; 2) return 0;\n CComPtr&lt;IShellItem&gt; spsiFolder;\n SHCreateItemFromParsingName(argv[1], nullptr,\n                             IID_PPV_ARGS(&amp;spsiFolder));\n\n CComPtr&lt;IEnumShellItems&gt; spesi;\n spsiFolder-&gt;BindToHandler(nullptr, BHID_EnumItems,\n                              IID_PPV_ARGS(&amp;spesi));\n\n for (CComPtr&lt;IShellItem&gt; spsi;\n      spesi-&gt;Next(1, &amp;spsi, nullptr) == S_OK;\n      spsi.Release()) {\n  <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/08\/30\/10202076.aspx\">PrintDisplayName<\/a>(spsi, SIGDN_NORMALDISPLAY, L\"Display Name\");\n  PrintDisplayName(spsi, SIGDN_FILESYSPATH, L\"File system path\");\n  wprintf(L\"\\n\");\n }\n return 0;\n}\n<\/pre>\n<p>Run this program with the fully-qualified path to a directory as the command line argument, and it enumerates all the items in the folder. This uses the default enumeration, which is &#8220;include both folders and non-folders, and include hidden items, but not super-hidden items.&#8221; <\/p>\n<p>But what if we want to customize the enumeration? <\/p>\n<p>We saw that the <code>IBindCtx<\/code> parameter <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/01\/22\/10587918.aspx\">acts as a catch-all <i>options<\/i> parameter<\/a>. In this case, we need to look at the options available for <code>BHID_Enum&shy;Items<\/code> and see if any of them help us. <\/p>\n<p>Fortunately, we have <code>STR_ENUM_ITEMS_FLAGS<\/code> which lets us override the default enumeration mode. Let&#8217;s say that we want only folders, and we want to respect the user&#8217;s preferences for hidden items (which means that we omit <code>SHCONTF_HIDDEN<\/code>). <\/p>\n<p>I&#8217;m goint to do this two ways. First the flat version: <\/p>\n<p><pre>\n ...\n <font COLOR=\"blue\">CComPtr&lt;IBindCtx&gt; spbcEnum;\n <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/01\/23\/10588226.aspx\">CreateDwordBindCtx<\/a>(STR_ENUM_ITEMS_FLAGS, SHCONTF_FOLDERS,\n                    &amp;spbcEnum);<\/font>\n\n CComPtr&lt;IEnumShellItems&gt; spesi;\n spsiFolder-&gt;BindToHandler(<font COLOR=\"blue\">spbcEnum<\/font>, BHID_EnumItems,\n                              IID_PPV_ARGS(&amp;spesi));\n<\/pre>\n<p>Now the fluent version: <\/p>\n<pre>\n ...\n <font COLOR=\"blue\"><a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/01\/23\/10588226.aspx\">CBindCtxBuilder<\/a> builder;\n builder.SetVariantDword(STR_ENUM_ITEMS_FLAGS, SHCONTF_FOLDERS);<\/font>\n\n CComPtr&lt;IEnumShellItems&gt; spesi;\n spsiFolder-&gt;BindToHandler(<font COLOR=\"blue\">builder.GetBindCtx()<\/font>, BHID_EnumItems,\n                              IID_PPV_ARGS(&amp;spesi));\n<\/pre>\n<p>(Don&#8217;t forget that error checking has been elided for expository purposes.) <\/p>\n<p>The <code>STR_ENUM_ITEMS_FLAGS<\/code> bind context string was added in Windows&nbsp;8, so it has no effect on older versions of Windows. We&#8217;ll address this next week. <\/p>\n<p>Note that the <code>IEnum&shy;Shell&shy;Items<\/code> interface is incorrectly-named. The convention for enumeration interfaces is to name them <code>IEnum&shy;XXX<\/code>, where XXX is <i>singular<\/i>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have it your way.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-44833","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Have it your way.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44833","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=44833"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44833\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=44833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=44833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=44833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}