How do I hide the contents of the desktop?

This is actually trivially easy, though in a non-obvious sort of way. The secret is knowing that Program Manager is alive and well and lurking around for backwards-compatibility reasons. If you get its handle and hide that window, all the icons on the desktop will magically vanish:

void ShowDesktopIcons (BOOL bShow)
{
   HWND hProgMan = ::FindWindow (NULL, "Program Manager") ;

   if (hProgMan)
   {
      if (bShow)
         ::ShowWindow (hProgMan, SW_SHOW);
      else
         ::ShowWindow (hProgMan, SW_HIDE);
   }
}

Simple. So what's the downside ?

  • The user won't be able to right-click the desktop and get a context menu.
  • The Policy system uses the same mechanism for denying access to the desktop, so if you provide switching capability in your program and the user has been denied access via policies, you'll be giving it back to them.

UPDATE:

I am indebted to Ryan Gruss for passing on this extra wrinkle. If you drill down two levels as shown below, you can get direct to the List View which hosts the icons. If you hide this, then you can clear up the desktop but still retain the context menu.

HWND hPMWnd, hLVWnd, hIconWnd;

hPMWnd = FindWindow ("Progman", "Program Manager");
hLVWnd = FindWindowEx (hPMWnd, NULL, "SHELLDLL_DefView", NULL);
hIconWnd = FindWindowEx (hLVWnd, NULL, "SysListView32",NULL);

ShowWindow (hIconWnd, SW_HIDE/SW_SHOW);

Thanks, Ryan :-)

Download