{"id":43713,"date":"2014-11-03T07:00:00","date_gmt":"2014-11-03T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/11\/03\/applying-a-filter-to-the-contents-of-an-explorer-browser\/"},"modified":"2014-11-03T07:00:00","modified_gmt":"2014-11-03T07:00:00","slug":"applying-a-filter-to-the-contents-of-an-explorer-browser","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20141103-00\/?p=43713","title":{"rendered":"Applying a filter to the contents of an Explorer Browser"},"content":{"rendered":"<p>\nToday&#8217;s Little Program hosts an Explorer Browser but filters\nthe contents to remove DLL files.\nYou can, of course, substitute your own filter.\n(For example, maybe you want to show only files that changed\nsince the last time the user ran your program,\nor you might want a view of My Computer but filtered to show\nonly removable drives.)\n<\/p>\n<p>\nRemember that Little Programs do little to no error checking,\nand they don&#8217;t necessarily demonstrate the best programming style.\nThey&#8217;re just quick demonstrations.\nToday&#8217;s smart pointer library is&hellip; (rolls dice) &hellip; WRL!\n<\/p>\n<p>\nStart with\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/03\/25\/10145644.aspx\">\nour minimal explorer browser program<\/a>\nand make these changes.\n<\/p>\n<pre>\n<font COLOR=\"blue\">#include &lt;shlwapi.h&gt; \/\/ PathFindExtensionW\n#include &lt;wrl\\client.h&gt;\n#include &lt;wrl\\implements.h&gt;\nusing namespace Microsoft::WRL;\nclass FolderFilterNoDLLs :\n    public RuntimeClass&lt;RuntimeClassFlags&lt;ClassicCom&gt;,\n                        IFolderFilter&gt;\n{\n \/\/ *** IFolderFilter ***\n IFACEMETHODIMP GetEnumFlags(IShellFolder *psf,\n    PCIDLIST_ABSOLUTE pidlFolder, HWND *phwnd,\n    DWORD *pgrfFlags) { return S_OK; }\n IFACEMETHODIMP ShouldShow(IShellFolder *psf,\n    PCIDLIST_ABSOLUTE pidlFolder,\n    PCUITEMID_CHILD pidlItem)\n {\n  BOOL fShow = TRUE;\n  ComPtr&lt;IShellItem&gt; spsi;\n  HRESULT hr = SHCreateItemWithParent(pidlFolder, psf, pidlItem,\n                                      IID_PPV_ARGS(&amp;spsi));\n  if (SUCCEEDED(hr)) {\n   SFGAOF sfgaof;\n   hr = spsi-&gt;GetAttributes(SFGAO_FILESYSTEM | SFGAO_FOLDER,\n                            &amp;sfgaof);\n   if (SUCCEEDED(hr) &amp;&amp; sfgaof == SFGAO_FILESYSTEM) {\n    LPWSTR pszName;\n    hr = spsi-&gt;GetDisplayName(SIGDN_PARENTRELATIVEPARSING,\n                                 &amp;pszName);\n    if (SUCCEEDED(hr))\n    {\n     fShow = CompareStringOrdinal(\n                 PathFindExtensionW(pszName), -1,\n                 L\".dll\", -1, TRUE) != CSTR_EQUAL;\n     CoTaskMemFree(pszName);\n    }\n   }\n  }\n  if (SUCCEEDED(hr)) hr = fShow ? S_OK : S_FALSE;\n  return hr;\n }\n};<\/font>\n<\/pre>\n<p>\nThe real work happens in the\n<code>Should&shy;Show<\/code> method.\n<\/p>\n<ul>\n<li>Create an <code>IShellItem<\/code> because it&#8217;s more convenient.\n<li>Query the <code>SFGAO_FILE&shy;SYSTEM<\/code> and\n    <code>SFGAO_FOLDER<\/code> attributes.<\/p>\n<li>If the attributes say &#8220;Yes, it&#8217;s a file system object,\n    and no, it&#8217;s not a folder&#8221;&#8230;<\/p>\n<ul>\n<li>Get the display name.\n<li>If the display name ends in <code>.dll<\/code>,\n        then hide the item.\n    <\/ul>\n<\/ul>\n<p>\nAll that&#8217;s left is to plug this into the Explorer Browser.\n<\/p>\n<pre>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n    BOOL fSuccess = FALSE;\n    RECT rc;\n    PIDLIST_ABSOLUTE pidl = NULL;\n    <font COLOR=\"blue\">ComPtr&lt;IFolderFilter&gt; spff;\n    ComPtr&lt;IFolderFilterSite&gt; spffs;<\/font>\n    if (SUCCEEDED(CoCreateInstance(CLSID_ExplorerBrowser, NULL,\n                         CLSCTX_INPROC, IID_PPV_ARGS(&amp;g_peb))) &amp;&amp;\n        GetClientRect(hwnd, &amp;rc) &amp;&amp;\n        SUCCEEDED(g_peb-&gt;Initialize(hwnd, &amp;rc, NULL)) &amp;&amp;\n        SUCCEEDED(g_peb-&gt;SetOptions(EBO_NAVIGATEONCE)) &amp;&amp;\n        <font COLOR=\"blue\">SUCCEEDED(MakeAndInitialize&lt;FolderFilterNoDLLs&gt;(&amp;spff)) &amp;&amp;\n        SUCCEEDED(g_peb-&gt;QueryInterface(IID_PPV_ARGS(&amp;spffs))) &amp;&amp;\n        SUCCEEDED(spffs-&gt;SetFilter(spff.Get())) &amp;&amp;<\/font>\n        SUCCEEDED(SHParseDisplayName(\n                         L\"C:\\\\Program Files\\\\Internet Explorer\",\n                                        NULL, &amp;pidl, 0, NULL)) &amp;&amp;\n        SUCCEEDED(g_peb-&gt;BrowseToIDList(pidl, SBSP_ABSOLUTE))) {\n        fSuccess = TRUE;\n    }\n    ILFree(pidl);\n    return fSuccess;\n}\n<\/pre>\n<p>\nWe apply the filter to the\n<code>IExplorerBrowser<\/code>\nby querying for <code>IFolder&shy;Filter&shy;Site<\/code>\nand using\n<code>IFolder&shy;Filter&shy;Site::Set&shy;Filter<\/code>\nto attach our &#8220;no DLLs&#8221; filter.\n<\/p>\n<p><b>\nBonus reading<\/b>:\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/10\/14\/10456386.aspx\">\nFiltering the folders that appear in the Browse for Folder dialog<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today&#8217;s Little Program hosts an Explorer Browser but filters the contents to remove DLL files. You can, of course, substitute your own filter. (For example, maybe you want to show only files that changed since the last time the user ran your program, or you might want a view of My Computer but filtered to [&hellip;]<\/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-43713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Today&#8217;s Little Program hosts an Explorer Browser but filters the contents to remove DLL files. You can, of course, substitute your own filter. (For example, maybe you want to show only files that changed since the last time the user ran your program, or you might want a view of My Computer but filtered to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/43713","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=43713"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/43713\/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=43713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=43713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=43713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}