Releasing hDC problems

Started by
3 comments, last by LessBread 18 years, 6 months ago
I'm having problems with releasing the device context.

/**
 * Destructor
 */
COpenGLDriver::~COpenGLDriver()
{

	if( hRC ){
		if( !wglMakeCurrent(0,0) )
			util::Message::print("COpenGLDriver::~COpenGLDriver: Release of DC and RC failed.");

		if( !wglDeleteContext(hRC) )
			util::Message::print("COpenGLDriver::~COpenGLDriver: Release of rendering context failed.");

		hRC = NULL;
	}

	if( ReleaseDC(Window, hDC) != 1 ){
		util::Message::print("COpenGLDriver::~COpenGLDriver: Could not release openGL dc.");
	}
	
	// Dodgy - I'm using the 'else if' as an &&
	// This will only execute if hRC == NULL and the ReleaseDC call succeeds.
	else if( hRC == NULL )
		util::Message::print("COpenGLDriver::~COpenGLDriver: OpenGL was uninitialized properly.");


	hDC = NULL;

}

Whenever I close my program, I always get "COpenGLDriver::~COpenGLDriver: Could not release openGL dc." printed out, and I can't figure out why. This is straight from MSDN Library, from VS 6.0:
Quote: int ReleaseDC( HWND hWnd, // handle to window HDC hDC // handle to device context ); The return value specifies whether the device context is released. If the device context is released, the return value is 1.
So, is there something that jumps out at people? Also (this is of secondary importance), in some of my constructors, I actually call 'return' during it, say, if something has gone wrong and the rest of the constructor should not be executed. Is this bad programming practice, or just plain bad?
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Advertisement
Depending on how you acquire your hDC, you may want to try calling DeleteDC instead of ReleaseDC.

Quote:Also (this is of secondary importance), in some of my constructors, I actually call 'return' during it, say, if something has gone wrong and the rest of the constructor should not be executed. Is this bad programming practice, or just plain bad?

It's bad. What clues do you have that the object couldn't be constructed and is invalid? Throw an exception instead.
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
Very often, DCs returned by GetDC do not need to be released at all. In particular, on the ReleaseDC MSDN page:

Quote:Class and private DCs do not have to be released.


I would strongly suspect that being an OpenGL windows, your DC is private. A private DC is one from a window with class style WS_OWNDC specified. In fact, if it's a top level window then it is highly unlikely to be using WS_PARENTDC which is the only one that needs releasing.

Also, bare in mind that ReleaseDC returns a status code, not an error code. It merely says whether the DC was released or not. It might not be released for perfectly harmless reasons. Actually, releasing a private DC qualifies as a harmless operation because it is well defined as having no effect.

Unfortunately, this is just one in a long line of irritating semantic inconsistencies with the Win32 API.
another thing u have to watch out for is if your destructor
is called after WM_NCDESTROY, the window handle is no longer
valid and the release dc function will fail. make sure to
call IsWindowValid (or is it IsValidWindow lol i forget i'm
not on my dev station).

for this reason, i don't destroy my OpenGL-related handles
in the destructor. i create InitGL and FreeGL functions and
I call one in WM_NCCREATE and the other in WM_NCDESTROY.
(or without the NC is fine too).

yadango
This tool can help resolve problems with GDI: gdiobj.zip
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

This topic is closed to new replies.

Advertisement