Drawing on the Background

Simply, is it possible to draw on the background using the WinAPI? I mean the desktop background, what you see when you have everything minimized.
Yeah, you just need the HWND to the desktop. Then you can paint to it like any other window.

I think there's a GetDesktopWindow() function which returns the HWND to the desktop, but I'm not sure.

*checks with MSDN*

Yep
So then, how exactly would I go about using it? Get the device context and simply draw using that? Don't I have to invalidate the rect containing the area too?
Sorry for double posting, but people don't seem to be able to tell when edits are made.

I've tried using GetDesktopWindow and InvalidateRect, it hasn't worked:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <windows.h>

int WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {

	HWND hwnd = GetDesktopWindow ( );

	RECT rect;
	rect.bottom = 400;
	rect.left = 200;
	rect.top = 200;
	rect.right = 400;

	HDC hdc = GetDC ( hwnd );
	for ( int i = 0; i < 20000; i++ ) {
		MoveToEx ( hdc, 200, 200, NULL );
		LineTo ( hdc, 400, 400 );
		InvalidateRect ( hwnd, &rect, true );
		Sleep ( 5 );
	}

	ReleaseDC ( hwnd, hdc );

	return 0;
}


That's what I'm using right now. Feel free to correct me.
LineTo uses the current pen. Maybe the desktop DC doesn't have a pen selected?

Try selecting a pen then doing that (and then putting the original pen back in, of course).
Sorry, I lost interest in the WinAPI after figuring out that it would be much faster to simply use DirectX (which should've been obvious from the beginning >.>), and so I don't know much about using pens. How exactly would I get the currently used pen?
Last edited on
Hah

I lost interest in WinAPI as soon as I found wx. This stuff is just from memory.

Anyway... I don't remember exactly how to create a pen and am too lazy to look it up, so I'll do this with a stock brush instead (that way there's less cleanup, too)

Plus -- it dawns on me that your RECT is wrong (it has a width and height of 0, so you're basically invalidating nothing).

Anyway here's my code that fills a 100x100 square with solid black. This ought to work:

1
2
3
4
5
6
7
8
9
10
11
12
13
  RECT rect;
  rect.top = 200;
  rect.left = 200;
  rect.right = 300;
  rect.bottom = 300;

  HDC hdc = GetDC ( hwnd );
  HBRUSH br = (HBRUSH)GetStockObject(BLACK_BRUSH);

  FillRect(hdc,&rect,br);
  ReleaseDC(hwnd,hdc);

  InvalidateRect(hwnd,&rect,true);  // I don't think this is necessary, actually 


Another problem might have been that you were invalidating the rect before you released the DC (and you weren't releasing the DC until after that massive loop). Keep in mind that the Desktop needs to get the DC to draw, which it can't do if your program takes it and holds onto it for extended periods of time.
Alright, so I'm now using this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ...
	HWND hwnd = GetDesktopWindow ( );

	RECT rect;
	rect.bottom = 800;
	rect.left = 600;
	rect.top = 600;
	rect.right = 800;

	HBRUSH br = (HBRUSH)GetStockObject(BLACK_BRUSH);

	for ( int i = 0; i < 20000; i++ ) {
		HDC hdc = GetDC ( hwnd );
		FillRect ( hdc, &rect, br );
		InvalidateRect ( hwnd, &rect, true );
		ReleaseDC ( hwnd, hdc );
		Sleep ( 5 );
	}
// ... 


Which doesn't work...

What I want to do is show the current CPU usage as a part of the background, like you can do in Gentoo. Is there another way to achieve this effect?
Nah, sorry, I'm out of ideas. Guess my WinAPI is rusty. =(
I'm asking on the MSDN, I'll keep this thread updated as I get more information. Someone might find this useful.

But if I figure out how to do this, and I actually complete the program, the end results should be pretty awesome. :)
Last edited on
I think the desktop window is a two part window - the bit with the icons (which is the part you are after) is a childwindow of the desktop (window) or something like that.
Topic archived. No new replies allowed.