How do I get the user-customed name of My Computer or Recycle Bin?


Today's Little Program displays the user-customized name of This PC (the folder formerly known as My Computer) or Recycle Bin. The basic principle here is that if you want to display something the same way that Explorer does, then ask the same data source that Explorer asks: The shell namespace.

Today's smart pointer library is (rolls dice) nothing. We're going to use raw pointers.

Remember, Little Programs do little to no error checking.

#define STRICT_TYPED_ITEMIDS
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <ole2.h>
#include <shlobj.h>
#include <stdio.h>

void PrintDisplayName(IShellItem* item, SIGDN sigdn, PCWSTR label)
{
  PWSTR name;
  item->GetDisplayName(sigdn, &name);
  printf("%ls = %ls\n", label, name);
  CoTaskMemFree(name);
}

void PrintKnownFolderDisplayName(
    REFKNOWNFOLDERID rfid, SIGDN sigdn, PCWSTR label)
{
  IShellItem* item;
  SHGetKnownFolderItem(rfid, KF_FLAG_DONT_VERIFY,
                       nullptr, IID_PPV_ARGS(&item));
  PrintDisplayName(item, sigdn, label);
  item->Release();
}

int __cdecl wmain(int argc, wchar_t **argv)
{
  CoInitialize(0);
  PrintKnownFolderDisplayName(FOLDERID_ComputerFolder,
    SIGDN_NORMALDISPLAY, L"name");
  PrintKnownFolderDisplayName(FOLDERID_RecycleBinFolder,
    SIGDN_NORMALDISPLAY, L"name");
  CoUninitialize();
  return 0;
}

The Print­Display­Name function obtains the display name of a shell item and prints it. The Print­Known­Folder­Display­Name function gets the item for a known folder and prints its display name. And our main program grabs the This PC and Recycle Bin folders and prints their display names.

Really not that complicated.

If you are old-school and prefer to work with shell folders and item ID lists, you can do it the old school way:

#define STRICT_TYPED_ITEMIDS
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <ole2.h>
#include <oleauto.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <stdio.h>
#include <tchar.h>

void PrintDisplayName(PCIDLIST_ABSOLUTE absolute, SHGDNF shgdn, PCWSTR label)
{
  IShellFolder* parentFolder;
  PCUITEMID_CHILD child;
  SHBindToParent(absolute, IID_PPV_ARGS(&parentFolder), &child);
  PrintDisplayName(parentFolder, child, shgdn, label);
  parentFolder->Release();
}

void PrintCsidlDisplayName(int csidl, SHGDNF shgdn, PCWSTR label)
{
  PIDLIST_ABSOLUTE absolute;
  SHGetFolderLocation(nullptr, csidl, nullptr, 0, &absolute);
  PrintDisplayName(absolute, shgdn, label);
  CoTaskMemFree(absolute);
}

int __cdecl wmain(int argc, wchar_t **argv)
{
  CoInitialize(0);
  PrintCsidlDisplayName(CSIDL_DRIVES, SHGDN_NORMAL, L"name");
  PrintCsidlDisplayName(CSIDL_BITBUCKET, SHGDN_NORMAL, L"name");
  CoUninitialize();
  return 0;
}

The idea is the same: We bind to the special folder and print its name. Getting the name of an object is done by asking the parent for the name of the child.

Okay, this isn't all that exciting, but it still shows that the way to get the name of something the way Explorer shows it is to get the name the way Explorer gets it.

I'll play with this a little more next week.

Comments (8)
  1. Adam Rosenfield says:

    I'm curious to know how many sides your smart pointer dice have and what all of the sides are.

  2. Joshua says:

    I wanna know where Raymond bought his d50.

  3. skSdnW says:

    Yay, more shell stuff, can't wait!

    Slightly off topic but could you maybe encourage the MSDN folks to document what SIGDN_PARENTRELATIVEFORUI does and when it should be used…

  4. Mark Y says:

    I have a hunch that he's not actually using dice, he's just doing what he feels like and blaming it on the dice to emphasize that it's utterly beside the point he's trying to make.  But I'd be curious to find out there are real dice involved!

  5. cheong00 says:

    @Joshua: I thought for pointer types, D20 is enough. D50 is going to have difficult moments to decide which side is "up" on uneven surface. (Or maybe that's how we get "nothing" as result?)

  6. Scarlet Manuka says:

    From various searches I found:

    * nothing

    * _com_ptr_t

    * CComPtr

    * WRL

    I thought I'd also once seen auto_ptr come up in a dice roll, but I couldn't find any such article, so perhaps not.

    I also found this comment on an earlier article:

    —-

    Nick

    > (rolls dice)

    I really hope you keep a die on your desk that you actually roll for these.

    [(Looks around nervously.) (whisper) The dice are loaded. -Raymond]

    —-

    I did notice _com_ptr_t coming up an awful lot in my searches :)

  7. Andreas says:

    @Scarlet: auto_ptr is deprecated, but perhaps std::unique_ptr or std::shared_ptr next?

  8. Pavel Kostromitinov says:

    Raymond, thank you for all these how-to posts!

    I have one small comment, though…

    For any half-decent developer (and i count myself among those) a single word or two would be enough to provide an answer (IShellItem::GetDisplayName in this case).

    Maybe you could highlight them, or even put them at the beginning?

    It would make the much-needed answer seen immediately in Google search results, for example…

Comments are closed.

Skip to main content