使用Graphics.GetHdc时参数无效异常

问题描述:

我一直在制作一个应用程序来拍摄网站快照。 一切运作良好,到现在为止: 我的应用已经拍很多照片,和图像拍摄的过程是为完成如下:使用Graphics.GetHdc时参数无效异常

using (Graphics graphics = Graphics.FromImage(mBitmap)) 
{ 
    IntPtr hdc = graphics.GetHdc(); 
    SendMessage(new HandleRef(mWebBrowser, mWebBrowser.Handle), 791, hdc, (IntPtr)30); 
    BitBlt(new HandleRef(graphics, hdc), 0, 0, mBitmap.Width, mBitmap.Height, new HandleRef(graphics, hdc), 0, 0, 13369376); 
    graphics.ReleaseHdc(); 
} 

(这是DrawToBitmap的代码从WebBrowser控件一个变。与ILSpy合作)。

IntPtr hdc = graphics.GetHdc();发生错误。线。

我在使用GetHdc方法时询问有人询问这个“参数是无效的”,人们说这可能是因为没有释放之前的GDI对象。这是不是这样,因为图形对象正在使用using语句,位图也是如此...

我需要说明的是,我有很多webbrowsers在同一时间(我从不摧毁它们,使用它们,这是我的另一个错误,这是我能解决它的唯一方法......)

当我在TaskManager上查看GDI对象的数量时,我看到它是一个巨大的量。但是 - 错误没有发生,当我碰巧有最GDI对象... 我猜这个数量的对象来自WebBrowsers ...?

从ILSpy原来DrawToBitmap代码:

int nWidth = Math.Min(this.Width, targetBounds.Width); 
int nHeight = Math.Min(this.Height, targetBounds.Height); 
Bitmap image = new Bitmap(nWidth, nHeight, bitmap.PixelFormat); 
using (Graphics graphics = Graphics.FromImage(image)) 
{ 
    IntPtr hdc = graphics.GetHdc(); 
    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), 791, hdc, (IntPtr)30); 
    using (Graphics graphics2 = Graphics.FromImage(bitmap)) 
    { 
     IntPtr hdc2 = graphics2.GetHdc(); 
     SafeNativeMethods.BitBlt(new HandleRef(graphics2, hdc2), targetBounds.X, targetBounds.Y, nWidth, nHeight, new HandleRef(graphics, hdc), 0, 0, 13369376); 
     graphics2.ReleaseHdcInternal(hdc2); 
    } 
    graphics.ReleaseHdcInternal(hdc); 
} 

文档声称的Webbrowser不支持DrawToBitmap,但它工作得很好,直到当它只是抛出此异常的某个阶段。

+1

可用句柄的_total_数量存在系统限制。但我认为这些日子相当高。 –

+0

我有点困惑,为什么你要为同一个调用创建多个'HandleRef'。你可能会更好地写'var href = new HandleRef(graphics,hdc)',然后将这两个地方的ref传递给'BitBlt'。这就是说,这显然不是问题?我也想知道你为什么要调用'BitBlt'而不是'Graphics.DrawImage'等。 –

+0

网页浏览器已隐藏。正如我在括号中所说的,这段代码与从System.windows.forms中的ILSPy获取的代码有所不同。我这样做是因为我想要对发生的事情有更高级别的控制,而不是仅仅使用WebBrowser.DrawToBitmap。感谢关于HandleRefs的评论。 –

即使这个职位是很老的我希望能帮助解决这个问题,因为我有同样的,我解决了它这种方式:

private static Graphics graphics = null; 
private static IntPtr hdc = IntPtr.Zero; 
private static IntPtr dstHdc = IntPtr.Zero; 

private static Capture() 
{ 
    if (graphics == null) 
    { 
     hdc = GetDC(IntPtr.Zero); 
     graphics = Graphics.FromImage(bitmap); 
     dstHdc = graphics.GetHdc(); 
    } 
    BitBlt(dstHdc, 0, 0, screen_resolution.Width, screen_resolution.Height, hdc, 0, 0, RasterOperation.SRC_COPY); 
} 

对我来说,解决办法是,我称之为graphics.GetHdc ()只有一次,当对象是零。之后,我从不使用调用graphics.GetHdc()。