13

I'm trying to make an application that needs to draw on the desktop, behind the icons so it appears to replace the desktop wallpaper. I've found a few solutions to this, but most of them didn't work very well (lots of flickering). One solution seems to be what I'm looking for, but I don't really get it. I've done mostly C# applications using either higher-level graphics libraries or just Windows Forms, and some C++ but only on non-Windows platforms.

If anyone could "translate" it for me or provide me with an alternative solution, it would be much appreciated!

nardi
  • 331
  • 1
  • 3
  • 9

5 Answers5

8

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?).

nardi
  • 331
  • 1
  • 3
  • 9
  • Sadly not, as far as I'm aware. I have kind of given up on what I was trying to do, seems like it's not really possible. – nardi Dec 12 '12 at 16:05
  • 3
    This is super late, but I was able to do it with this [link](http://www.codeproject.com/Articles/856020/Draw-Behind-Desktop-Icons-in-Windows). – Clark Aug 11 '15 at 05:53
  • @Clark you could post it as an answer in my opinion. It is the answer to this question, and would make finding it more easy for who ends up in this page. Also OP should set it as correct answer. – Barnack May 14 '19 at 14:24
2

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

Géal
  • 1,482
  • 11
  • 13
2

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.

darclander
  • 1,526
  • 1
  • 13
  • 35
1

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

William Jarvis
  • 347
  • 3
  • 6
0

Yes, with interop, see this thread.

luvieere
  • 37,065
  • 18
  • 127
  • 179
  • That would draw on top of everything; I'm looking to draw behind everything (except the desktop wallpaper). – nardi Nov 06 '09 at 09:20