2011-12-10 65 views
5

Tôi đã tạo một ứng dụng để chụp nhanh các trang web. Tất cả mọi thứ hoạt động tốt, cho đến bây giờ: Tôi có ứng dụng chụp ảnh NHIỀU, và quá trình việc lấy hình ảnh được thực hiện như sau:Tham số là Ngoại lệ không hợp lệ khi sử dụng 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(); 
} 

(đây là một độ khác nhau của mã của DrawToBitmap từ sự kiểm soát WebBrowser được thực hiện với ILSpy).

Lỗi xảy ra trên IntPtr hdc = graphics.GetHdc(); hàng.

Tôi đã tìm kiếm những người hỏi về "Thông số này không hợp lệ" khi sử dụng phương pháp GetHdc và mọi người cho rằng đó có thể là do không phát hành các đối tượng GDI trước đó. đây không phải là trường hợp, kể từ khi đối tượng đồ họa là với một tuyên bố sử dụng, và như vậy là bitmap ...

Tôi cần lưu ý rằng tôi có nhiều webbrowsers cùng một lúc (tôi không bao giờ tiêu diệt chúng, tôi lại- sử dụng chúng, đây là một lỗi khác mà tôi đã có và đây là cách duy nhất tôi có thể giải quyết nó ...)

Khi tôi nhìn vào TaskManager trên số lượng đối tượng GDI, tôi thấy nó là một số tiền. Nhưng - lỗi không xảy ra khi tôi tình cờ có nhiều đối tượng GDI nhất ... Tôi đoán rằng số lượng đối tượng này đến từ WebBrowsers ...?

Mã DrawToBitmap gốc từ ILSpy là:

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); 
} 

Các tài liệu tuyên bố rằng WebBrowser không hỗ trợ DrawToBitmap, nhưng nó hoạt động độc đáo cho đến khi một số giai đoạn khi nó chỉ ném ngoại lệ này.

+1

Có giới hạn hệ thống đối với tổng số lượng xử lý có sẵn _total_. Nhưng tôi nghĩ nó khá cao trong những ngày này. –

+0

Tôi hơi bối rối vì sao bạn tạo nhiều 'HandleRef' cho cùng một cuộc gọi. Bạn có lẽ tốt hơn bằng cách viết 'var href = new HandleRef (đồ họa, hdc)', và sau đó chuyển ref đó trong cả hai nơi để 'BitBlt'. Điều đó nói rằng, nó dường như không phải là vấn đề? Tôi cũng tự hỏi tại sao bạn đang gọi 'BitBlt' thay vì sử dụng' Graphics.DrawImage' hoặc somesuch. –

+0

Trình duyệt web bị ẩn. như tôi đã nói trong ngoặc đơn, mã này đã được thay đổi từ mã được lấy từ ILSPy trên System.windows.forms. Tôi đã làm điều đó bởi vì tôi muốn có một mức độ kiểm soát cao hơn về những gì happends, thay vì chỉ sử dụng WebBrowser.DrawToBitmap. Cảm ơn bạn đã bình luận về HandleRefs. –

Trả lời

1

Ngay cả bài đăng này là rất cũ tôi muốn giúp đỡ để giải quyết vấn đề này, bởi vì tôi có giống nhau và tôi giải quyết nó theo cách này:

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); 
} 

Các giải pháp đối với tôi là, mà tôi gọi là graphics.GetHdc() chỉ một lần khi đối tượng là Zero. Sau đó tôi không bao giờ sử dụng gọi graphics.GetHdc().

Các vấn đề liên quan