I have been making an application to take snapshots of websites. Everything works well, until now: I have the application take MANY photos, and the process of the image taking is done as following:
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();
}
(this is a varying of the code of DrawToBitmap from the WebBrowser control. taken with ILSpy).
The error occurs on the IntPtr hdc = graphics.GetHdc(); line.
I sought for people asking about this "Parameter is Invalid" when using the GetHdc method, and people said that it might be because of not releasing prior GDI objects. this is not the case, since the Graphics object is withing a using statement, and so is the bitmap...
I need to note that I have many webbrowsers at the same time (I never destroy them, I re-use them, this is for another error which I had and this was the only way I could solve it...)
When I'm looking on the TaskManager on the amount of GDI Object, I see it is a huge amount. But - the error did not occur when I happened to have the most GDI Objects... I guess that this amount of objects comes from the WebBrowsers...?
The original DrawToBitmap code from ILSpy is:
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);
}
The documentation claims that Webbrowser does not support DrawToBitmap, but it works nicely until some stage when it just throws this exception.
Even this post is very old I want to help to solve this problem, because I had the same and I solved it this way:
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);
}
The solution for me was, that I call graphics.GetHdc() only one time when the object is Zero. After that I never use call graphics.GetHdc().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With