views:

651

answers:

5

How Would I go about placing text on the windows desktop? I've been told that GetDesktopWindow() is what I need but I need an example.

+2  A: 

This question might help you. It's about the same thing your asking here, and provides a complete example on how to do it.

Lucas McCoy
I've tried that with TextOut substituted and and it's just erased as soon as it's written and only part of it is shown
sowas
Err my bad. that does do What I said, but I'd like the text to stay even after windows are moved over it.
sowas
@sowas: That's going to be hard to accomplish. Windows tend to redraw everything on the screen when there moved. You'll need to have your text redraw itself while the Window is moving. I'll try and find a way to do that.
Lucas McCoy
+7  A: 

I'm assuming your ultimate goal is displaying some sort of status information on the desktop.

You will have to do either:

  • Inject a DLL into Explorer's process and subclass the desktop window (the SysListView32 at the bottom of the Progman window's hierarchy) to paint your text directly onto it.

  • Create a nonactivatable window whose background is painted using PaintDesktop and paint your text on it.

First solution is the most intrusive, and quite hard to code, so I would not recommend it.

Second solution allows the most flexibility. No "undocumented" or reliance on a specific implementation of Explorer, or even of just having Explorer as a shell.

In order to prevent a window from being brought to the top when clicked, you can use the extended window style WS_EX_NOACTIVATE on Windows 2000 and up. On downlevel systems, you can handle the WM_MOUSEACTIVATE message and return MA_NOACTIVATE.

You can get away with the PaintDesktop call if you need true transparency by using layered windows, but the concept stays the same. I wrote another answer detailing how to properly do layered windows with alpha using GDI+.

Koro
+1  A: 

Why not just draw the text in the desktop wallpaper image file?

This solution would be feasible if you don't have to update the information too often and if you have a wallpaper image.

One can easily use CImage class to load the wallpaper image, CImage::GetDC() to obtain a device context to draw into, then save the new image, and finally update the desktop wallpaper to the new image.

Cristian Adam
I had already thought of that but the data has to be updated frequently.
sowas
A: 

i haven't tried but i assume you could do the following:

  1. use GetDesktopWindow to retrieve the handle of the desktop window
  2. use SetWindowLong to point the windows message handler to your own procedure
  3. in your proc, process the WM_PAINT message (or whatever) and draw what you need.
  4. in your proc, call the original message handler (as returned by SetWindowLong).

not 100% sure it will work, but seems like it should as this is the normal way to subclass a window.

-don

Don Dickinson
That would crash twice: Once when Explorer.EXE fails to call your own procedure (it's in your process, not Explorer). If we could ignore that, it would crash when you'd try to call the original WndProc in Explorer's process, not yours.
MSalters
A: 

If your intent is to produce something like the Sidebar, you probably just want to create one or more layered windows. That will also allow you to process mouse clicks and other normal sources of input, and if you supply the alpha channel information, Windows will make sure that your window is drawn properly at all times. If you don't want the window to be interactive, use appropriate styles (such as WS_EX_NOACTIVATE) like Koro suggests.

Morbo