{"id":92721,"date":"2015-12-28T07:00:00","date_gmt":"2015-12-28T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=92721"},"modified":"2019-03-13T12:23:17","modified_gmt":"2019-03-13T19:23:17","slug":"20151228-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20151228-00\/?p=92721","title":{"rendered":"Determining how each Explorer window is sorted"},"content":{"rendered":"<p>Today&#8217;s Little Program lists all the open Explorer windows and their current sort criteria. (I will refrain from mentioning how auto-sort makes this meaningful.) Remember that Little Programs do little to no error checking. <\/p>\n<pre>\n#define STRICT\n#include &lt;windows.h&gt;\n#include &lt;ole2.h&gt;\n#include &lt;shlobj.h&gt;\n#include &lt;shdispid.h&gt;\n#include &lt;atlbase.h&gt;\n#include &lt;atlalloc.h&gt;\n#include &lt;stdio.h&gt;\n\nvoid ProcessOneWindow(IUnknown *punk)\n{\n CComPtr&lt;IShellBrowser&gt; spsb;\n if (FAILED(IUnknown_QueryService(punk, SID_STopLevelBrowser,\n                                  IID_PPV_ARGS(&amp;spsb)))) return;\n\n CComPtr&lt;IShellView&gt; spsv;\n if (FAILED(spsb-&gt;QueryActiveShellView(&amp;spsv))) return;\n\n CComQIPtr&lt;IFolderView2&gt; spfv(spsv);\n if (!spfv) return;\n\n CComHeapPtr&lt;WCHAR&gt; spszLocation;\n if (FAILED(<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/06\/10\/10424662.aspx\">GetLocationFromView<\/a>(spsb, &amp;spszLocation))) return;\n\n printf(\"Location = %ls\\n\", static_cast&lt;PCWSTR&gt;(spszLocation));\n\n int cColumns;\n if (FAILED(spfv-&gt;GetSortColumnCount(&amp;cColumns))) return;\n if (cColumns &gt; 10) cColumns = 10;\n\n SORTCOLUMN rgColumns[10]; \/\/ arbitrary number\n spfv-&gt;GetSortColumns(rgColumns, cColumns);\n\n for (int i = 0; i &lt; cColumns; i++) {\n  PCWSTR pszDir = rgColumns[0].direction &gt; 0 ? L\"ascending\"\n                                             : L\"descending\";\n  PCWSTR pszName;\n  CComHeapPtr&lt;WCHAR&gt; spszName;\n  WCHAR szName[PKEYSTR_MAX];\n  if (SUCCEEDED(PSGetNameFromPropertyKey(rgColumns[0].propkey,\n                                         &amp;spszName))) {\n   pszName = spszName;\n  } else {\n   PSStringFromPropertyKey(rgColumns[0].propkey,\n                           szName, ARRAYSIZE(szName));\n   pszName = szName;\n  }\n  printf(\"Column = %ls, direction = %ls\\n\", pszName, pszDir);\n }\n}\n\nint __cdecl wmain(int, wchar_t **)\n{\n <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">CCoInitialize<\/a> init;\n CComPtr&lt;IShellWindows&gt; spShellWindows;\n spShellWindows.CoCreateInstance(CLSID_ShellWindows);\n\n CComPtr&lt;IUnknown&gt; spunkEnum;\n spShellWindows-&gt;_NewEnum(&amp;spunkEnum);\n CComQIPtr&lt;IEnumVARIANT&gt; spev(spunkEnum);\n\n for (CComVariant svar;\n      spev-&gt;Next(1, &amp;svar, nullptr) == S_OK;\n      svar.Clear()) {\n  ProcessOneWindow(svar.pdispVal);\n }\n return 0;\n}\n<\/pre>\n<p>To process a window, we first ask for the top-level browser, and from that we ask for the active shell view, then convert it to an <code>IFolder&shy;View2<\/code>. We ask for the 2 because that&#8217;s the one that lets us query sort columns. <\/p>\n<p>If anything goes wrong up to this point, it&#8217;s probably because the window doesn&#8217;t support sorting, so we won&#8217;t bother printing it. <\/p>\n<p>We print the location of the window using a helper function from a long time ago. <\/p>\n<p>Now the interesting part: We ask for the number of sort columns, then ask for those columns. <\/p>\n<p>That&#8217;s it. The rest is boring again: We print each of the sort columns and the sort direction. <\/p>\n<p>The main program loops through all the open Shell windows (which includes both Explorer and Internet Explorer) and processes each one. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ask for the sort criteria.<\/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-92721","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Ask for the sort criteria.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92721","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=92721"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92721\/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=92721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=92721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=92721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}