ReleaseDC

when I use ReleaseDC on a HDC that I got with GetDC ( which didn’t fail ), ReleaseDC returns ERROR_INVALID_PARAMETER. Way is this?

Maybe you should post some code…

this is the create and destroy code

bool Window::Create()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};

if (!( Hdc = GetDC( Hwnd ) ))
{
ErrorInternal( eeErrorInternal_GetDC );
return false;
}

GLuint PixelFormat;

if (!( PixelFormat = ChoosePixelFormat( Hdc, &pfd ) ))
{
ErrorInternal( eeErrorInternal_ChoosePixelFormat );
return false;
}

if( !SetPixelFormat( Hdc, PixelFormat, &pfd ))
{
ErrorInternal( eeErrorInternal_SetPixelFormat );
return false;
}

if (!( Hglrc = wglCreateContext( Hdc ) ))
{
ErrorInternal( eeErrorInternal_wglCreateContext );
return false;
}

return true;
};

bool Window: estroy()
{
bool Return = true;

if ( Hglrc != NULL )
{
if ( !wglMakeCurrent( NULL, NULL) )
{
ErrorInternal( eeErrorInternal_wglMakeCurrent );
Return = false;
}

  if ( !wglDeleteContext( Hglrc ) )
  {
  	ErrorInternal( eeErrorInternal_wglDeleteContext );
  	Return = false;
  }

  Hglrc = NULL;

}

if ( Hdc && !ReleaseDC( Hwnd, Hdc ) ) {
ErrorInternal( eeErrorInternal_ReleaseDC );
Return = false;

  Hdc = NULL;

}

return Return;
}

[This message has been edited by ARES (edited 01-28-2002).]

Someone???

You’re not making the rendering context current, for a start.

I do wglMakeCurrent( NULL, NULL ) at the start of the destroy function???

This is sample…

bool bDestroyWindow(HWND hWnd)
{
if( !g_HGLRC && !g_HDC )
return false;

if( g_HGLRC )											
{
	wglMakeCurrent(NULL, NULL);				// This frees our rendering memory and sets everything back to normal
	wglDeleteContext(g_HGLRC);				// Delete our OpenGL Rendering Context	
}

if( g_HDC )
	ReleaseDC(g_HWND, g_HDC);				// Release our HDC from memory

UnregisterClass(szWindowClass, hInst);		// Free the window class
PostQuitMessage (0);						// Post a QUIT message to the window

return true;

}

That is the same as my code.

OK!

Change this …

if ( Hdc && !ReleaseDC( Hwnd, Hdc ) )

to …

if ( Hdc && ReleaseDC( Hwnd, Hdc ) )

You want the ReleaseDC to return true to indicate that it’s succeded. Your logic is back to front!

PS. With regard to my previous post. After You use the wglCreateContext(), you should really then use wglMakeCurrent(hdc, hglrc) to make the rendering context valid for the calling thread. This won’t actually matter in a single threaded environment, but it’s a good practice to get into - just in case you ever have multiple threads.

[This message has been edited by Shag (edited 02-02-2002).]

No than it will always say that it went wrong.

I found that the last windows error is ERROR_INVALID_PARAMETER. Which doesn’t make sense???

PS. I do call wglMakeCurrent in an other function that is called after Create().

Sorry - I was too tired when I wrote that!

and yes, use MakeCurrent after Create

I do call wglMakeCurrent in an other function that is called after Create().

Does nobody know???

You know, you don’t have to release the DC of a classed window.

Here’s my shutdown code:

if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,“Release Of RC Failed.”,“SHUTDOWN ERROR”,MB_OK | MB_ICONINFORMATION);
}

if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL,“Deletion of Rendering Context Failed.”,“SHUTDOWN ERROR”,MB_OK | MB_ICONINFORMATION);
}
hRC=NULL;// Set RC To NULL
}

hDC=NULL;// Set DC To NULL - don’t have to ReleaseDC on a DC belonging to a class window

if (hWnd)
{
if (!DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,“Could Not Destroy Window!”,“SHUTDOWN ERROR”,MB_OK | MB_ICONINFORMATION);
}
hWnd=NULL; // Set hWnd To NULL
}

if (!UnregisterClass(“engine”,hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,“Could Not Unregister Class!”,“SHUTDOWN ERROR”,MB_OK | MB_ICONINFORMATION);
}
hInstance=NULL; // Set hInstance To NULL

It works fine.

Care,
Chris
Florida, USA
RTS Engine in Development http://www.knology.net/~heaven/rts.htm

The msdn says:

An application must call the ReleaseDC function for each call to the GetDC function that retrieves a common DC.

From MSDN Home > MSDN Library > Windows GDI > Device Contexts > Device Context Reference > Device Context Functions:

“The ReleaseDC function releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs.”

From MSDN Home > MSDN Library > Windows GDI > Device Contexts > About Device Contexts > Device Context Types:

"… Private device contexts are not part of the system cache and therefore need not be released after use. The system automatically removes a private device context after the last window of that class has been destroyed.

An application creates a private device context by first specifying the CS_OWNDC window-class style when it initializes the style member of the WNDCLASS structure and calls the RegisterClass function. (For more information about window classes, see Window Classes.)"

So what I meant to say was, “You know, you don’t have to release the DC of a window created with the CS_OWNDC or CS_CLASSDC styles.”

Care,
Chris
RTS Engine in Development http://www.knology.net/~heaven/rts.htm

The window isn’t created with the CS_OWNDC or CS_CLASSDC styles.

It is also strange that it only gives this error on my friends computer and not on mine. But we both have win98.

Well, CS_CLASSDC is only present for compatibility with 16 bit Windows, so you should avoid it, but you should really specify CS_OWNDC for the window class used by your OpenGL window. From earlier in the paragraph quoted about private device context deletion:

“Private device contexts are display device contexts that, unlike common device contexts, retain any changes to the default data — even after an application releases them. Private device contexts are used in applications that perform numerous drawing operations such as computer-aided design (CAD) applications, desktop-publishing applications, drawing and painting applications, and so on…”

I’d have to say that most OpenGL applications fit the description of an appropriate use of private DCs.

–Travis Cobbs

The documentation for GetDC says this:

"Note that the handle to the DC can only be used by a single thread at any one time."

I believe (but I’m not sure) that the message handler runs in a separate thread. So if the Destroy function is being called from the message handler, that might be the problem.