Printing the name and position of the focused item on the desktop


Today's Little Program prints the name and position of the focused item on the desktop. Remember, Little Programs do little to no error checking.

#define UNICODE
#define _UNICODE
#include "stdafx.h"
#include <windows.h>
#include <shlobj.h>
#include <exdisp.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlalloc.h>
#include <stdio.h>

int __cdecl wmain(int argc, wchar_t **argv)
{
  CCoInitialize init;
  CComPtr<IFolderView> spView;
  FindDesktopFolderView(IID_PPV_ARGS(&spView));
  CComPtr<IShellFolder> spFolder;
  spView->GetFolder(IID_PPV_ARGS(&spFolder));

  int iItem;
  if (FAILED(spView->GetFocusedItem(&iItem))) {
    wprintf(L"Sorry, no focused item.\n");
    return 0;
  }

  CComHeapPtr<ITEMID_CHILD> spidl;
  spView->Item(iItem, &spidl);

  STRRET str;
  spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
  CComHeapPtr<wchar_t> spszName;
  StrRetToStr(&str, spidl, &spszName);

  wprintf(L"Focused item is %ls\n", static_cast<LPWSTR>(spszName));
  spszName.Free();

  spFolder->GetDisplayNameOf(spidl, SHGDN_FORPARSING, &str);
  StrRetToStr(&str, spidl, &spszName);
  wprintf(L"Parsing name is %ls\n", static_cast<LPWSTR>(spszName));

  POINT pt;
  spView->GetItemPosition(spidl, &pt);
  wprintf(L"Position is %d, %d\n", pt.x, pt.y);

  return 0;
}

We actually have most of the necessary pieces lying around already.

After initializing COM and getting the desktop folder view, we get the underlying IShell­Folder because we're going to need it in order to interpret the pidls that come out later.

We ask the view for the index of the focused item. If it can't cough one up, then we apologize and exit.

Otherwise, we use that index to get the corresponding pidl and then ask the folder to convert it into a normal name (which is the name shown under the icon) and a parsing name (which for files is the full path name).

Finally, we ask for the item position.

There you have it, a little program that identifies the current focused item on the desktop.

Comments (7)
  1. Mike Diack says:

    Incidental (non-error checking comment) - Am I not right in thinking you should not use the preprocessor at all (for #define or #include) before #including a precompiled header? You seem to have done that with the Unicode #defines?

    Useful code though!

    1. Darran Rowe says:

      You are right there. But you also don't normally need to define the Unicode defines because Visual Studio puts them on the command line.
      Also, don't forget, stdafx.h is only a precompiled header if you set it to be one. If you create a console application using the basic win32 template, you have a choice to add a precompiled header. If you deselect it, the default template still uses the same files which include stdafx.h.

    2. JFG says:

      Certain #define names/values flag an option in the header, so it *must* be done before the header is included.

    3. Henri Hein says:

      You will understand that I can not fail to refuse to disagree with you.

  2. James says:

    I'm probably not being very imaginative, but in what circumstances would something care about the focused desktop item (especially as opposed to the currently selected item(s))?

  3. Ray Koopa says:

    I can't think of any use-case for this... who would do that? =3 Though, coding wise surely interesting...

Comments are closed.

Skip to main content