Connecting some blocks: Tell me more about the current image in my wallpaper slide show

One of my colleagues said,

I really like the wallpaper slide show feature, especially the one that rotates through the top-rated pictures in my photo library. My photo library includes photos taken by other members of my family, and sometimes I'll get a wallpaper that I want to learn more about. It'd be great if there were some way to say "Hey, tell me more about this wallpaper."

Today's Little Program snaps together some blocks.

  • It registers a command on the desktop background.
  • The command looks at the current wallpaper image.
  • And then shows you some information about it in the form of a property sheet.

(My colleague actually preferred that the image be opened in Photo Gallery, but I'll just show the properties because not every has Photo Gallery installed, and the purpose of the exercise is to show how to snap blocks together, not to argue about which color blocks to use.)

#define UNICODE
#define _UNICODE
#define STRICT
#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>
#include <atlbase.h>
#include <atlalloc.h>

void ShowProperties(PCWSTR pszFile)
 SHELLEXECUTEINFO sei = { sizeof(sei) };
 sei.nShow = SW_SHOWNORMAL;
 sei.lpVerb = L"properties";
 sei.lpFile = pszFile;

 CCoInitialize init;
 ProcessReference ref;

 // The rest of this code is adapted from
 // Obtaining information about the user's wallpaper on multiple monitors

 CComPtr<IDesktopWallpaper> spdw;
 CoCreateInstance(CLSID_DesktopWallpaper, nullptr, CLSCTX_ALL,

 CComHeapPtr<wchar_t> spszCommonWallpaper;
 HRESULT hr = spdw->GetWallpaper(nullptr, &spszCommonWallpaper);
 if (hr == S_OK) {
  // Single wallpaper on all monitors.
 } else if (hr == S_FALSE) {
  // Different wallpaper on each monitor.
  // Look for the monitor that has the mouse pointer.
  POINT pt;

  UINT count;

  for (UINT i = 0; i < count; i++) {
   // Get the device path for the monitor.
   CComHeapPtr<wchar_t> spszId;
   spdw->GetMonitorDevicePathAt(i, &spszId);

   // Get the monitor location.
   RECT rc;
   spdw->GetMonitorRECT(spszId, &rc);
   if (PtInRect(&rc, pt)) {
    // Get the wallpaper on that monitor.
    CComHeapPtr<wchar_t> spszWallpaper;
    hr = spdw->GetWallpaper(spszId, &spszWallpaper);

 return 0;

Now we get to hook this up to the context menu for the desktop.

[HKEY_CLASSES_ROOT\DesktopBackground\shell\Wallpaper properties\command]

Now you can right-click on the desktop background and select Wallpaper properties, and it will show you the properties of the wallpaper. You are of course welcome to do something else, like load the wallpaper into your favorite image viewer.

Note that I cheated a bunch here. In addition to pretty much ignoring all error checking (because this is a Little Program), I also use the current mouse position instead of using the point at which the context menu was invoked.

Comments (11)
  1. That was one your best blog posts in a long time, Raymond.

    [I get the feeling that comment volume is inversely proportional to article quality. -Raymond]
  2. cheong00 says:

    Is there a way to open the currently registered property sheets handler without DDE?

    [Not sure what you mean. Are you saying, "If the property sheet handler requires DDE, then fail"? I guess you could remove the DDEWAIT flag. -Raymond]
  3. samlh says:

    Thanks, this will help me with one of my personal toy programs :)

  4. cheong00 says:

    I mean, as there are advice to stop using DDE(…/1763683.aspx ), maybe there is other way to invoke the currently registered property sheets handler?

    Just want to check if there are other ways.

    [That article is saying "You are free to stop using DDE as a way to launch your application." That's not the same as saying "You are free to refuse to launch other applications that use DDE." If the property sheet requires DDE, then you have to accept that launching the property sheet requires DDE. -Raymond]
  5. xpclient says:

    Would be nicer if you could open a specific property sheet e.g. Details tab directly.

    [How would you make that work in Japanese? How would you even be sure that the property sheet has a Details tab in the first place? -Raymond]
  6. cheong00 says:

    Well, I sited that article because it's the first one returned by "dde stop using"… Anyway I guess I should stop here.

  7. cheong00 says:

    I mean "cited"… where is the edit button when I need them? :P

  8. Matt says:

    As a long time reader I'd really enjoy seeing more deeper technical posts (e.g, why it was decided pages allocated via AWE cannot be mapped to more than one virtual address)

  9. Boris says:

    [I get the feeling that comment volume is inversely proportional to article quality. -Raymond]

    What if you snapped in a Windows 8 block?

  10. Joshua says:

    [How would you even be sure that the property sheet has a Details tab in the first place? -Raymond]

    Because it's a file property sheet.

    [Maybe the next version of Windows removed the Details tab and migrated its contents to other pages? -Raymond]
  11. xpclient says:

    [How would you make that work in Japanese? How would you even be sure that the property sheet has a Details tab in the first place?]

    Gee I don't know. Why/how do the Properties for .LNK files open directly on the Shortcut tab starting with the IE4 Windows Update Update? Before that, always the General tab opened. What if the Shortcut tab got removed in the future?

    [The shortcut property sheet knows that it has a Shortcut page because it put it there. It's like replying to "Application Q's window hierarchy is not documented" with "But then how can Application Q find its windows?" .-Raymond]

Comments are closed.

Skip to main content