37

I'm trying to work on a project where I can animate the windows 7 wallpaper, either with opengl/directx, or GDI. I looked into how the windows desktop windows are laid out, and i figured out the whole

"Progman" -> "SHELLDLL_DefView" -> "SysListView32"

hierarchy. I tried hooking the SysListView32's WndProc and tried messing around with the messages using an injected c# dll so I could prevent the desktop from drawing the wallpaper when I forced it to change using the Control Panel -> Personalize menu. None of this actually stopped the wallpaper from being updated, so I figured that explorer.exe does not actually handle drawing the wallpaper.

To confirm this, I killed explorer.exe and set up a little c# program that changes the wallpaper on a 10 second timer to a random one. As I expected, the wallpaper kept changing, leading me to believe that explorer.exe does not actually handle the drawing of the wallpaper!

Unfortunately, this is where i'm completely lost. I have no idea what else is responsible for drawing the wallpaper, and how I can take over it's drawing so I can handle the drawing. I've tried to google this for a few days now, with little progress. I'm hoping someone here can guide me in the right direction.

logisticalerror
  • 391
  • 3
  • 5
  • 18
    [`GetDesktopWindow`](https://msdn.microsoft.com/en-us/library/ms633504) returns a handle for the desktop window with the wallpaper. In Windows 7 this window has a kernel-mode window procedure `win32k!xxxDesktopWndProc` (from win32k.sys), which calls `win32k!xxxInternalPaintDesktop`. Related functions are `win32k!xxxDrawWallpaper` and `win32k!xxxSetDeskWallpaper`. There's also user-mode [`PaintDesktop`](https://msdn.microsoft.com/en-us/library/dd162758), which eventually calls `win32k!xxxInternalPaintDesktop`. – Eryk Sun Jun 04 '15 at 20:42
  • 3
    @eryksun: This should be an answer. – Yakov Galka Jun 05 '15 at 11:36
  • 5
    The vlc media player has a feature to show a video as desktop wallpaper. You could check out how they do it (probably the way @eryksun described) – this.myself Jun 16 '15 at 07:01
  • 3
    @this.myself, I've looked into the VLC source, and managed to replicate it. It just uses a DirectX Overlay and sets the wallpaper to a single color. Unfortunately this doesn't work very well for my purposes since the edges of text look weird, and dragging across the desktop to select multiple items makes the color change so the overlay doesn't draw where the selection box is. – logisticalerror Jun 16 '15 at 10:41
  • does this help? http://stackoverflow.com/questions/1061678/change-desktop-wallpaper-using-code-in-net – Chris Hawkes Jun 29 '15 at 12:54
  • @Chris no, unfortunately. I can already change the wallpaper to a static image. What I want to be able to do is (preferrably) render directly to the wallpaper using OpenGL or DirectX. I can partially do this using DirectDraw Overlays, but this isn't perfect. – logisticalerror Jul 04 '15 at 09:55
  • 1
    BS.Player and VLC have this feature. You can try [this post][1] for starting. [1]: https://stackoverflow.com/questions/12416960/how-does-vlc-play-videos-on-the-desktop – Adrian Stanculescu Jul 14 '15 at 07:15

2 Answers2

1

The Desktop (including the Bitmap on it) is actually drawn by the window system itself. So that is basically quite deep and old, too. So according to the changes that happened since NT4 I suppose that the painting is actually done in win32k.sys . The driver was created to replace win32.dll which would have done everything in user-mode with context switching.

This said, it goes conform with what erykson commented to your question: win32k!xxxInternalPaintDesktop is the bad guy.

However it should be possible to acquire the DC of the Desktop HWND (0 afaik) and attach it to your own drawing. Not sure if you can turn it into a DirectX DC but this is up to you to try.

BTW. It is possible to re-parent and to capture foreign windows (HWNDs) and associated device contexts (DCs). However you might need to be privileged or an administrator. (security checked)

StarShine
  • 1,940
  • 1
  • 27
  • 45
Robetto
  • 739
  • 7
  • 20
  • I've been able to GetDC(0) and draw to it, but this draws above the desktop icons, so I can't exactly use it for my purposes. I'll look into somehow hooking `win32k!xxxInternalPaintDesktop`. – logisticalerror Jul 30 '15 at 23:21
  • You're drawing "above" the icons because Explorer does not draw after you again. Because Explorer basically does the same. So this is an ordinary painter effect (one erases the prev) – Robetto Jul 31 '15 at 10:01
  • So I should be able to grab Explorer's WM_PAINT, do my painting then, and then let Explorer do it's paint? – logisticalerror Aug 01 '15 at 05:18
  • Sounds like it its possible. Unless... if Explorer wants to clear the background before it's drawing your're screwed. But otherwise it should be possible to re-route or re-issue the WM_PAINT message to make explorer.exe paint HWND 0. However: No concrete Idea, right now. – Robetto Aug 04 '15 at 13:49
0

The Desktop Window Manager is responsible for drawing the wallpaper. It is implemented as a Windows Service.