2011-12-10 85 views
5

我一直在製作一個應用程序來拍攝網站快照。 一切運作良好,到現在爲止: 我的應用已經拍很多照片,和圖像拍攝的過程是爲完成如下:使用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的評論。 –

回答

1

即使這個職位是很老的我希望能幫助解決這個問題,因爲我有同樣的,我解決了它這種方式:

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