通过将屏幕截图保存到BMP,我被要求调试一些试图在VB.Net中制作图形电影的代码。我发现它在达到10,000 GDI对象的限制后失败,并确定泄漏来自此代码:
Dim r As Integer
Dim hdcdest As System.IntPtr = CType(CreateCompatibleDC(CInt(GetWindowDC(frmDynamicsMDI.MainControl.fraAnimation.Handle))), IntPtr)
Dim hdcbitmap As System.IntPtr = CType(CreateCompatibleBitmap(GetWindowDC(frmDynamicsMDI.MainControl.fraAnimation.Handle), _
frmDynamicsMDI.MainControl.fraAnimation.Size.Width - (0 + CropRight), _
frmDynamicsMDI.MainControl.fraAnimation.Size.Height - (10 + 0)), IntPtr)
SelectObject(hdcdest, CInt(hdcbitmap))
BitBlt(hdcdest, 0, 0, frmDynamicsMDI.MainControl.fraAnimation.Width - (0 + CropRight), frmDynamicsMDI.MainControl.fraAnimation.Height - (10 + 0), _
GetWindowDC(frmDynamicsMDI.MainControl.fraAnimation.Handle), 0, 10, 13369376)
Image = System.Drawing.Image.FromHbitmap(hdcbitmap)
r = DeleteDC(CInt(GetWindowDC(frmDynamicsMDI.MainControl.fraAnimation.Handle)))
DeleteObject(CInt(hdcdest))
DeleteObject(CInt(hdcbitmap))
BitBlt声明为:
Private Declare Function BitBlt Lib "GDI32" (ByVal hdestDC As IntPtr, ByVal x As Integer, ByVal y As Integer, _
ByVal nwidth As Integer, ByVal nheight As Integer, ByVal HsrcDC As IntPtr, ByVal xsrc As Integer, ByVal ysrc As Integer, ByVal _
dwRop As Int32) As Boolean
2 System.IntPtr
创建调用每个创建2个GDI对象,'BitBlt'创建1.我发现的问题是DeleteObject()
调用每个只删除1个GDI对象。
删除调用是否正确完成?或者是否有其他对象浮动与未被删除的GDI对象?
答案 0 :(得分:3)
GetWindowDC用于窗口非客户区域内的特殊绘画效果。不建议在任何窗口的非客户区域进行绘画。
绘制完成后,必须调用ReleaseDC函数以释放设备上下文。不释放窗口设备上下文会严重影响应用程序请求的绘制。
您的代码在多个位置调用GetWindowDC。尝试只调用一次变量,然后在完成后使用ReleaseDC。