1

在 Windows 窗体的背面,我得到一个窗口 DC,使用 创建一个 Graphics 对象Graphics.FromHdc,然后在释放 DC之前处置 Graphics 对象。

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

Microsoft 文档Graphics.FromHdc显示了类似的代码。(它使用Graphics.GetHdcand Graphics.ReleaseHdc,而不是 Win32GetWindowDc和。)但是,它们在释放Graphics 对象之前ReleaseDC释放 DC :

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

他们为什么这样做?DC应该在之前还是之后发布Graphics.Dispose?错误的顺序可能会导致资源泄漏或内存损坏吗?

4

1 回答 1

2

从 Graphics.Dispose 方法:

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

所以它似乎会自行释放hdc。

[编辑]

它实际上是:

[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

于 2012-06-01T05:37:08.020 回答