How to take the snapshot of a IE webpage through a BHO (C#)

Posted by Kapil on Stack Overflow See other posts from Stack Overflow or by Kapil
Published on 2010-03-26T08:57:44Z Indexed on 2010/05/06 0:18 UTC
Read the original article Hit count: 734

Filed under:


I am trying to build an IE BHO in C# for taking the snapshot of a webpage loaded in the IE browser. Here is what I'm trying to do:

public class ShowToolbarBHO : BandObjectLib.IObjectWithSite

    IWebBrowser2 webBrowser = null;

    public void SetSite (Object site)
        if (site != null)
            webBrowser = (IWebBrowser2)site;

Also, I p/invoke the following COM methods:

    public interface IViewObject
        void Draw([MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [MarshalAs(UnmanagedType.LPStruct)] ref COMRECT lprcBounds, [In] IntPtr lprcWBounds, IntPtr pfnContinue, int dwContinue);
        int GetColorSet([MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hicTargetDev, [Out] IntPtr ppColorSet);
        int Freeze([MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, out IntPtr pdwFreeze);
        int Unfreeze([MarshalAs(UnmanagedType.U4)] int dwFreeze);
        int SetAdvise([MarshalAs(UnmanagedType.U4)] int aspects, [MarshalAs(UnmanagedType.U4)] int advf, [MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink);
        void GetAdvise([MarshalAs(UnmanagedType.LPArray)] out int[] paspects, [MarshalAs(UnmanagedType.LPArray)] out int[] advf, [MarshalAs(UnmanagedType.LPArray)] out IAdviseSink[] pAdvSink);

    public class COMRECT
        public int left;
        public int top;
        public int right;
        public int bottom;

        public COMRECT()

        public COMRECT(int left, int top, int right, int bottom)
            this.left = left;
   = top;
            this.right = right;
            this.bottom = bottom;

    public interface IAdviseSink
        void OnDataChange([In]IntPtr pFormatetc, [In]IntPtr pStgmed);
        void OnViewChange([MarshalAs(UnmanagedType.U4)] int dwAspect, [MarshalAs(UnmanagedType.I4)] int lindex);
        void OnRename([MarshalAs(UnmanagedType.Interface)] object pmk);
        void OnSave();
        void OnClose();

Now When I take the snapshot:

I make a call CaptureWebScreenImage((IHTMLDocument2) webBrowser.document);

public static Image CaptureWebScreenImage(IHTMLDocument2 myDoc) {

        int heightsize = (int)getDocumentAttribute(myDoc, "scrollHeight");
        int widthsize = (int)getDocumentAttribute(myDoc, "scrollWidth");

        Bitmap finalImage = new Bitmap(widthsize, heightsize);
        Graphics gFinal = Graphics.FromImage(finalImage);
        COMRECT rect = new COMRECT();
        rect.left = 0; = 0;
        rect.right = widthsize;
        rect.bottom = heightsize;

        IntPtr hDC = gFinal.GetHdc();
        IViewObject vO = myDoc as IViewObject;

        vO.Draw(1, -1, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)hDC, ref rect, (IntPtr)0, (IntPtr)0, 0);


        return finalImage;


I am not getting the image of the webpage. Rather I am getting an image with black background. I am not sure if this is the right way of doing it, but I found over the web that IViewObject::Draw method is used for taking the image of a webpage in IE.

I was earlier doing the image capture using the Native PrintWindow() method as mentioned in the following codeproject's page -

But the image size is humongous! I was trying to see if I can reduce the size by using other techniques. It would be great if someone can point out the mistakes (I am sure there would be many) in my code above.

Thanks, Kapil

© Stack Overflow or respective owner

Related posts about iwebbrowser2

Related posts about bho