Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parameter is Invalid Exception when using Graphics.GetHdc

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.

like image 498
Nati Cohen Avatar asked Nov 14 '22 13:11

Nati Cohen


1 Answers

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

like image 82
nxexo007 Avatar answered Nov 16 '22 04:11

nxexo007