Hexagonal
Hexagonal

Reputation: 13

Release DC before or after Graphics.Dispose?

On the back of a Windows Form, I get a window DC, create a Graphics object with Graphics.FromHdc, and then dispose the Graphics object before releasing the DC.

Private Declare Function GetWindowDC Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As Integer

Dim hdc As IntPtr = GetWindowDC(Me.Handle)

Try
    Using g As Graphics = Graphics.FromHdc(hdc)
        ' ... use g ...
    End Using
Finally
    ReleaseDC(Me.Handle, hdc)
End Try

The Microsoft documentation for Graphics.FromHdc shows similar code. (It uses Graphics.GetHdc and Graphics.ReleaseHdc, instead of Win32 GetWindowDc and ReleaseDC.) However, they release the DC before disposing the Graphics object:

' Get handle to device context.
Dim hdc As IntPtr = e.Graphics.GetHdc()

' Create new graphics object using handle to device context.
Dim newGraphics As Graphics = Graphics.FromHdc(hdc)

' Draw rectangle to screen.
newGraphics.DrawRectangle(New Pen(Color.Red, 3), 0, 0, 200, 100)

' Release handle to device context and dispose of the Graphics  ' object
e.Graphics.ReleaseHdc(hdc)
newGraphics.Dispose()

Why did they do it this way? Should the DC be released before or after Graphics.Dispose? It is possible that the wrong order can cause resource leaks or memory corruption?

Upvotes: 1

Views: 1678

Answers (1)

Roger Johansson
Roger Johansson

Reputation: 23214

From the Graphics.Dispose method:

private void Dispose(bool disposing)
{
..SNIP...
    if (this.nativeGraphics != IntPtr.Zero)
    {
        try
        {
            if (this.nativeHdc != IntPtr.Zero) <<---
            {
                this.ReleaseHdc(); <<--- 
    }

So it seems like it will release the hdc by itself tbh.

[edit]

It's actually :

[DllImport("gdiplus.dll", CharSet = CharSet.Unicode, EntryPoint = "GdipReleaseDC",     ExactSpelling = true, SetLastError = true)]
private static extern int IntGdipReleaseDC(HandleRef graphics, HandleRef hdc);

That is getting called, don't know if the gdiplus release dc handles native device contexts too

Upvotes: 2

Related Questions