Drawing on the desktop background as wallpaper replacement (Windows/C#)

I know this is a pretty late answer but I recently looked into it myself and if further user's have the same issue this might help them.

NOTE: This answer is for C++ but maybe it might help you do the same in C#

As mentioned in a comment above I followed This guide to understand how I would be able to draw ON the windows wallpaper window.

By using these two methods:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
    HWND p = FindWindowEx(hwnd, NULL, "SHELLDLL_DefView", NULL);
    HWND* ret = (HWND*)lParam;

    if (p)
        {
        // Gets the WorkerW Window after the current one.
        *ret = FindWindowEx(NULL, hwnd, "WorkerW", NULL);
        }
    return true;
}

HWND get_wallpaper_window() {
        // Fetch the Progman window
        HWND progman = FindWindow("ProgMan", NULL);
        // Send 0x052C to Progman. This message directs Progman to spawn a 
        // WorkerW behind the desktop icons. If it is already there, nothing 
        // happens.
        SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);
        // We enumerate all Windows, until we find one, that has the SHELLDLL_DefView 
        // as a child. 
        // If we found that window, we take its next sibling and assign it to workerw.
        HWND wallpaper_hwnd = nullptr;
        EnumWindows(EnumWindowsProc, (LPARAM)&wallpaper_hwnd);
        // Return the handle you're looking for.
        return wallpaper_hwnd;
}

I was able to retrieve the windows handle.

Since I was only familiar with SDL this was the only solution I found but I believe that any ways that allows you to create / modify a window based on another window should work.

window = SDL_CreateWindowFrom((void*)get_wallpaper_window());

The line above allowed me to create a window in SDL from the HWND retrieved by the get_wallpaper_window() method.

Since there is a lot of code involved I will link my solution on github. This can draw a lot of stars (although I believe it can be improved) behind your desktop icons.


Seen this question in passing and I did partially solve the problem (But not in a way I can give any useful code) to make some cool games although might not have the application you want:

  • Set desktop background back to normal and take a screenshot of the desktop
  • Set desktop background black and take a screenshot of the desktop
  • Set desktop background white and take a screenshot of the desktop
  • Combine the black and white versions to make a mask and the first screenshot as the overlay setting pixel values that are different transparent.

Now on your form draw the following in order:

  1. Draw the first screenshot
  2. Draw your form stuff
  3. Draw the desktop overlay you created

This is what I did for a full screen form but could be adapted for non full screen forms quite easily I think. Essentially you have recreated the desktop but with the ability to do anything with it including some cool games. The draw speed and performance is satisfactory for any application but desktop interactivity is an issue... :( Here is a pic of a tanks game using the principle except I set the background white and made all white backgrounds transparent too!

My Tanks Game


I never found the solution I wanted, but here are the best (only?) alternatives:

  • Draw to the "SysListView32" window (ProgMan -> SHELLDLL_DefView -> SysListView32). This will draw behind the desktop icons, but will flicker when animation is used. How to: Link (you'll have to use interop in .NET).

  • Use DirectDraw overlays. You set the desktop color to a certain obscure color and everything with that color will be replaced with what's on the overlay. This is used in the example in my question and in the VLC wallpaper mode. However, this is incompatible with Aero. How to: Link (I guess you could use Managed DirectX in .NET?).


You can find inspiration in the VLC media player code. there's a wallpaper mode that does what you're looking for.