2011-12-10 16 views
5

kullanırken geçersizdir Web sitelerinin anlık görüntülerini çekmek için bir uygulama yapıyorum. Her şey şu ana kadar iyi çalışır: Başvuru BİRÇOK fotoğraf çekmek zorunda ve görüntü alma işlemi şu şekilde gerçekleştirilmektedir:Parametre, 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(); 
} 

(bu WebBrowser denetimi DrawToBitmap ait bir kod olarak değiştirilmesi, olan ILSpy ile alınmıştır.

Hata, IntPtr üzerinde gerçekleşir hdc = graphics.GetHdc(); hat.

GetHdc yöntemini kullanırken bu "Parametre Geçersiz" hakkında sorular soran insanlar aradı ve insanlar bunun önceden GDI nesnelerinin yayınlanmaması nedeniyle olabileceğini söyledi. Bu durum, Graphics nesnesi bir kullanım ifadesiyle dolduğundan ve bu nedenle bitmap ...

Aynı anda birçok web tarayıcım olduğunu not etmem gerekir (onları asla yok etmem, Onları kullanıyorum, bu vardı başka bir hata için ve bu çözmek için tek yoldu ...)

GDI Nesnesi miktarı üzerinde TaskManager'ı aradığımda, bunun çok büyük olduğunu görüyorum Miktar. Ama - GDI Nesneleri en fazla olanı aldığımda hata oluşmadı ... Bu miktarda nesne WebBrow'lardan geliyor sanırım ...?

ILSpy orijinal DrawToBitmap kodudur:

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

dokümantasyon Webbrowser DrawToBitmap desteklemediği iddia, ancak bu sadece bu istisna atar bir aşamada kadar güzel çalışıyor. Aynı vardı ve bu şekilde çözmüş çünkü

+1

Kullanılabilir tutamaçların _total_ miktarı için bir sistem sınırı vardır. Ama bu günlerde oldukça yüksek olduğunu düşündüm. –

+0

Aynı çağrı için neden çoklu 'HandleRef' oluşturduğunuzu biraz kafam karıştı. Muhtemelen yazarak “var href = new HandleRef (graphics, hdc)” yazıp daha sonra her iki yerde de “BitBlt” e geçmeniz daha iyidir. Yani, görünüşe göre sorun değil mi? Ayrıca neden "Graphics.DrawImage" veya somesuch kullanmak yerine 'BitBlt' dediğinizi merak ediyorum. –

+0

Web tarayıcısı gizlendi. parantez içinde söylediğim gibi bu kod, System.windows.forms üzerindeki ILSPy'den alınan bir koddan değiştirildi. Bunu yaptım çünkü sadece WebBrowser.DrawToBitmap kullanmak yerine, daha fazla kontrol sahibi olmak istedim. HandleRefs hakkında yorum için teşekkürler. –

cevap

1

Hatta bu mesaj, bu sorunu çözmek için yardımcı olmak istiyoruz çok eskidir:

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

benim için çözüm Ben graphics.GetHdc dediğimiz oldu() Nesne Sıfır olduğunda sadece bir kez. Bundan sonra asla grafikler kullanmam.GetHdc().