Determining how each Explorer window is sorted


Today'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.

#define STRICT
#include <windows.h>
#include <ole2.h>
#include <shlobj.h>
#include <shdispid.h>
#include <atlbase.h>
#include <atlalloc.h>
#include <stdio.h>

void ProcessOneWindow(IUnknown *punk)
{
 CComPtr<IShellBrowser> spsb;
 if (FAILED(IUnknown_QueryService(punk, SID_STopLevelBrowser,
                                  IID_PPV_ARGS(&spsb)))) return;

 CComPtr<IShellView> spsv;
 if (FAILED(spsb->QueryActiveShellView(&spsv))) return;

 CComQIPtr<IFolderView2> spfv(spsv);
 if (!spfv) return;

 CComHeapPtr<WCHAR> spszLocation;
 if (FAILED(GetLocationFromView(spsb, &spszLocation))) return;

 printf("Location = %ls\n", static_cast<PCWSTR>(spszLocation));

 int cColumns;
 if (FAILED(spfv->GetSortColumnCount(&cColumns))) return;
 if (cColumns > 10) cColumns = 10;

 SORTCOLUMN rgColumns[10]; // arbitrary number
 spfv->GetSortColumns(rgColumns, cColumns);

 for (int i = 0; i < cColumns; i++) {
  PCWSTR pszDir = rgColumns[0].direction > 0 ? L"ascending"
                                             : L"descending";
  PCWSTR pszName;
  CComHeapPtr<WCHAR> spszName;
  WCHAR szName[PKEYSTR_MAX];
  if (SUCCEEDED(PSGetNameFromPropertyKey(rgColumns[0].propkey,
                                         &spszName))) {
   pszName = spszName;
  } else {
   PSStringFromPropertyKey(rgColumns[0].propkey,
                           szName, ARRAYSIZE(szName));
   pszName = szName;
  }
  printf("Column = %ls, direction = %ls\n", pszName, pszDir);
 }
}

int __cdecl wmain(int, wchar_t **)
{
 CCoInitialize init;
 CComPtr<IShellWindows> spShellWindows;
 spShellWindows.CoCreateInstance(CLSID_ShellWindows);

 CComPtr<IUnknown> spunkEnum;
 spShellWindows->_NewEnum(&spunkEnum);
 CComQIPtr<IEnumVARIANT> spev(spunkEnum);

 for (CComVariant svar;
      spev->Next(1, &svar, nullptr) == S_OK;
      svar.Clear()) {
  ProcessOneWindow(svar.pdispVal);
 }
 return 0;
}

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 IFolder­View2. We ask for the 2 because that's the one that lets us query sort columns.

If anything goes wrong up to this point, it's probably because the window doesn't support sorting, so we won't bother printing it.

We print the location of the window using a helper function from a long time ago.

Now the interesting part: We ask for the number of sort columns, then ask for those columns.

That's it. The rest is boring again: We print each of the sort columns and the sort direction.

The main program loops through all the open Shell windows (which includes both Explorer and Internet Explorer) and processes each one.

Comments (11)
  1. Yuri Khan says:

    Why are there paragraphs in your preformatted text?

    1. Another bug in the server software. I've opened a ticket.

      1. Tim says:

        De-paragraphing will help but, also, any chance you could set line-height: normal here too (CSS selector is .entry-content pre)? I like the new design for the most part but the code is too spread out now and it used to look so lovely on your blog.

        1. Tightened it up. I haven't yet had a chance to do a full CSS makeover on the site. (Actually, I kind of like the open look. But there are a bunch of random issues mostly related to the server software screwing with my HTML.)

          1. Tim says:

            Thanks, I think it looks a lot better. Probably not for any legitimate design reason but because I'm used to looking at code in a text editor all day with no additional line height.

          2. Kirby FC says:

            And just for good measure, the URL here was changed.

          3. GSerg says:

            When the migration happened, the old URL, blogs.msdn.microsoft.com/b/oldnewthing, would redirect to the new URL.

            Then after several days, for less than a day, there was a short period when entering the old URL would take you to the true old blog with the last post being the one before the transition. I enjoyed the great old looks, but before I could grab the actual css for the benefit of the user style we now have, it was gone, and the old URL was redirecting to the new site again.

            Recently there was another change, now the old URL results in 404.

            Not sure if any of that is a correct behaviour, so I thought I'd let you know.
            Also I think it would be great if we could have the actual old css as a user style, this way we could please both people who hate the new look and who love it.

  2. nikos says:

    GetSortColumnCount implies that there could be more than one sort columns in explorer!? But how do you sort by more than one column?

    1. Ben Voigt says:

      Programmatically, using IFolderView2::SetSortColumns

  3. alegr1 says:

    Do you feel lucky, punk? How about I query your service?

    QueryService(punk,

    1. David Totzke says:

      @alegr1 LOL. Nice one.

Comments are closed.

Skip to main content