Win32: Rendering to the desktop?

Hi guys,

I need to be able to render OpenGL direct to the desktop window, as the app 3DTop does (

I thought I’d just need to get the DC of the desktop window and tie an OpenGL RC to this, but I can’t seem to get it to work. Any ideas or demos??

Thanks in advance for any help/advice you can offer.

Best regards,

Couldn’t you just create a Window without a border, menu, etc, and get the same effect?

Hmmm, maybe. I’m looking at maybe doing it the way you suggested but with the HWND_BOTTOM flag set to position it at the bottom of the z order. Then I could capture the WM_ACTIVATE messsage & when the app loses the focus, use SetWindowPos to set the z order flag back to HWND_BOTTOM again. This way the window should stay below all the other windows but cover the desktop.

However, it’d still be more elegant to render direct to the desktop window - I know it’s possible to get a DC onto it, just don’t know how!!

I suppose you could use:

HWND h_wndDesktop=GetDesktopWindow();
HDC h_dcDesktop=GetDC(h_wndDesktop);

My only concern is that then, you will have to setup the pixelformat for your DC… But it should have been done already when the window is created by Windows… The thing is, you can setup the pixelformat more than once for each window… And I suppose it is not a good idea to destroy the desktop window and then recreate it !!!

So, I am not sure you can avoid creating a bottomleast (opposite to topmost !) window…



Though it is possible to get DC handle to desktop, it is not recommended for one case - you cannot change it’s state - only read it.
You may use GetDC ( NULL ) to retrieve DC for current monitor’s desktop ( win98/2k only ), or in more general case GetDC ( GetDesktopWindow ( ) ) for current desktop DC on win95/nt or greater.

Read-only? Ahhh… which would explain why strange things happen when I try the following… I end up with a flickery desktop but still only seeing my wallpaper

GLuint PixelFormat; // Holds The Results After Searching For A Match


static	PIXELFORMATDESCRIPTOR pfd=				// pfd Tells Windows How We Want Things To Be
	sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor
	1,											// Version Number
	PFD_DRAW_TO_WINDOW |						// Format Must Support Window
	PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL
	PFD_DOUBLEBUFFER,							// Must Support Double Buffering
	PFD_TYPE_RGBA,								// Request An RGBA Format
	bits,										// Select Our Color Depth
	0, 0, 0, 0, 0, 0,							// Color Bits Ignored
	0,											// No Alpha Buffer
	0,											// Shift Bit Ignored
	0,											// No Accumulation Buffer
	0, 0, 0, 0,									// Accumulation Bits Ignored
	16,											// 16Bit Z-Buffer (Depth Buffer)  
	0,											// No Stencil Buffer
	0,											// No Auxiliary Buffer
	PFD_MAIN_PLANE,								// Main Drawing Layer
	0,											// Reserved
	0, 0, 0										// Layer Masks Ignored

if (!(hDC=GetDC(hWnd)))							// Did We Get A Device Context?
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Can't Create A GL Device Context on the desktop","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

MessageBox(NULL,"Got hWnd on desktop & DC on it!!","ERROR",MB_OK|MB_ICONEXCLAMATION);

if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// Did Windows Find A Matching Pixel Format?
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// Are We Able To Set The Pixel Format?
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

if (!(hRC=wglCreateContext(hDC)))				// Are We Able To Get A Rendering Context?
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

if(!wglMakeCurrent(hDC,hRC))					// Try To Activate The Rendering Context
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

ShowWindow(hWnd,SW_SHOW);						// Show The Window
SetForegroundWindow(hWnd);						// Slightly Higher Priority
SetFocus(hWnd);									// Sets Keyboard Focus To The Window
ReSizeGLScene(width, height);					// Set Up Our Perspective GL Screen

if (!InitGL())									// Initialize Our Newly Created GL Window
	KillGLWindow();								// Reset The Display
	MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;								// Return FALSE

MessageBox(NULL,"We're up!!","Status",MB_OK|MB_ICONEXCLAMATION);

The desktop window is using GDI or directdraw to draw you wallpaper, and the icons. And as far as i know it is not allowed to use opengl (double buffered) and directdraw/gdi in one window.


well, win2k sure doesn’t like 3dtop… thats all, I can say… it flickers from the background to its startup screen and never complets “loading icons”, er something…

Strange, 3dTop works fine for me on Win2K (TNT2 M64)… But anyway, I’ve got it working perfectly with capturing the WM_ACTIVATE message and sending the window to the bottom of the z-order with SetPosition.

Thanks for all your help and suggestions guys

Maybe another solution:

Use active desktop. Create the opengl stuff as a activeX control. Create a html page and insert it onto your desktop.