# ReleaseDC

**URL:** <https://community.khronos.org/t/releasedc/24517>\
**Category:** OpenGL: Basic Coding\
**Created:** [January 27, 2002, 10:03am UTC](https://community.khronos.org/t/releasedc/24517 "2002-01-27T10:03:00Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [January 27, 2002, 10:03am UTC](https://community.khronos.org/t/releasedc/24517/1 "2002-01-27T10:03:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Platinum](https://community.khronos.org/letter_avatar_proxy/v4/letter/p/f14d63/32.png) [@Platinum](https://community.khronos.org/u/Platinum)\
**Post date:** [January 27, 2002, 10:18pm UTC](https://community.khronos.org/t/releasedc/24517/2 "2002-01-27T22:18:00Z")

</div>

Maybe you should post some code…

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [January 28, 2002, 9:25am UTC](https://community.khronos.org/t/releasedc/24517/3 "2002-01-28T09:25:00Z")

</div>

this is the create and destroy code

> ```auto
> 
> ```

> 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;  
> }

> ```auto
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [January 31, 2002, 9:37am UTC](https://community.khronos.org/t/releasedc/24517/4 "2002-01-31T09:37:00Z")

</div>

Someone???

---

<div class="post-metadata">

**Author:** ![Shag](https://community.khronos.org/letter_avatar_proxy/v4/letter/s/b782af/32.png) [@Shag](https://community.khronos.org/u/Shag)\
**Post date:** [January 31, 2002, 9:48am UTC](https://community.khronos.org/t/releasedc/24517/5 "2002-01-31T09:48:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 1, 2002, 9:54am UTC](https://community.khronos.org/t/releasedc/24517/6 "2002-02-01T09:54:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Miguel\_dup1](https://community.khronos.org/letter_avatar_proxy/v4/letter/m/91b2a8/32.png) [@Miguel\_dup1](https://community.khronos.org/u/Miguel_dup1)\
**Post date:** [February 1, 2002, 11:40am UTC](https://community.khronos.org/t/releasedc/24517/7 "2002-02-01T11:40:00Z")

</div>

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;

```

}

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 2, 2002, 9:22am UTC](https://community.khronos.org/t/releasedc/24517/8 "2002-02-02T09:22:00Z")

</div>

That is the same as my code.

---

<div class="post-metadata">

**Author:** ![Shag](https://community.khronos.org/letter_avatar_proxy/v4/letter/s/b782af/32.png) [@Shag](https://community.khronos.org/u/Shag)\
**Post date:** [February 2, 2002, 5:47pm UTC](https://community.khronos.org/t/releasedc/24517/9 "2002-02-02T17:47:00Z")

</div>

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).]

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 3, 2002, 9:23am UTC](https://community.khronos.org/t/releasedc/24517/10 "2002-02-03T09:23:00Z")

</div>

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().

---

<div class="post-metadata">

**Author:** ![Shag](https://community.khronos.org/letter_avatar_proxy/v4/letter/s/b782af/32.png) [@Shag](https://community.khronos.org/u/Shag)\
**Post date:** [February 3, 2002, 12:42pm UTC](https://community.khronos.org/t/releasedc/24517/11 "2002-02-03T12:42:00Z")

</div>

Sorry - I was too tired when I wrote that!

and yes, use MakeCurrent after Create

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 4, 2002, 9:46am UTC](https://community.khronos.org/t/releasedc/24517/12 "2002-02-04T09:46:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 6, 2002, 9:34am UTC](https://community.khronos.org/t/releasedc/24517/13 "2002-02-06T09:34:00Z")

</div>

Does nobody know???

---

<div class="post-metadata">

**Author:** ![Heaven](https://community.khronos.org/letter_avatar_proxy/v4/letter/h/cc9497/32.png) [@Heaven](https://community.khronos.org/u/Heaven)\
**Post date:** [February 9, 2002, 12:13pm UTC](https://community.khronos.org/t/releasedc/24517/14 "2002-02-09T12:13:00Z")

</div>

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](http://www.knology.net/~heaven/rts.htm)

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 10, 2002, 9:48am UTC](https://community.khronos.org/t/releasedc/24517/15 "2002-02-10T09:48:00Z")

</div>

The msdn says:

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

---

<div class="post-metadata">

**Author:** ![Heaven](https://community.khronos.org/letter_avatar_proxy/v4/letter/h/cc9497/32.png) [@Heaven](https://community.khronos.org/u/Heaven)\
**Post date:** [February 11, 2002, 1:23am UTC](https://community.khronos.org/t/releasedc/24517/16 "2002-02-11T01:23:00Z")

</div>

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](http://www.knology.net/~heaven/rts.htm)

---

<div class="post-metadata">

**Author:** ![ARES](https://community.khronos.org/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@ARES](https://community.khronos.org/u/ARES)\
**Post date:** [February 11, 2002, 9:40am UTC](https://community.khronos.org/t/releasedc/24517/17 "2002-02-11T09:40:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![tcobbs](https://community.khronos.org/letter_avatar_proxy/v4/letter/t/f6c823/32.png) [@tcobbs](https://community.khronos.org/u/tcobbs)\
**Post date:** [February 11, 2002, 8:38pm UTC](https://community.khronos.org/t/releasedc/24517/18 "2002-02-11T20:38:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Jambolo](https://community.khronos.org/letter_avatar_proxy/v4/letter/j/0ea827/32.png) [@Jambolo](https://community.khronos.org/u/Jambolo)\
**Post date:** [February 13, 2002, 8:34pm UTC](https://community.khronos.org/t/releasedc/24517/19 "2002-02-13T20:34:00Z")

</div>

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.
