Showing posts with label PictureBox. Show all posts
Showing posts with label PictureBox. Show all posts

Sunday, June 3, 2007

MSHTML, Dom, and copying objects from a WebBrowser Control

While working on grabbing an image from a WebBrowser (talked about in my last post), I stumbled upon this method. It does work; however, it has one draw back: It only works for single framed images (ie. No animated images). Though, to be honest, I didn't play around all that much to see if I could finagle it to work with animated images.

I found this method of a foreign site and half the code was gone so I had to drum up the rest by sorting through the MSDN help files. I'm not quite sure if anyone else has looked up any DOM type stuff there, but as far as I can tell it's all quite dated and any real useful information is sparse and hard to come by. Luckily, with time I was able to piece together enough to determine the appropriate castings.

Alright, you have a WebBrowser control, and there's a particular element on it that you want. If it's text, I'd suggest just parsing the DocumentText variable of the control, but if it's an image, then this is a definite possible solution if you don't feel comfortable with the one here (the previous post going over a little bit simpler method which also handles sessions).

Before posting the code (straight from my project), I would like to point out that I didn't end up using this method and it was mostly testing. I still think that for some people it might pose useful and so I'm posting it. I still suggest looking at the previous post that covers a bit easier method before using this.

Code:
mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)
    webBrowser1.Document.DomDocument;
mshtml.IHTMLSelectionObject sobj = doc.selection;
mshtml.HTMLBody body = doc.body as mshtml.HTMLBody;
sobj.empty();
mshtml.IHTMLControlRange range = body.createControlRange() as
    mshtml.IHTMLControlRange;
mshtml.IHTMLControlElement img = (mshtml.IHTMLControlElement)     webBrowser1.Document.Images[0].DomElement;

range.add(img);
range.select();
range.execCommand("Copy", false, null);

Bitmap bimg = new Bitmap(Clipboard.GetImage());
pictureBox1.Image = bimg;

Grabbing secure data from the web.

Recently, I was working on a little image recognition for some anti-bot type image. No no, I wasn't working on any spamming type of application, just a little side project of mine.

Regardless, I needed to load the image from a website while being logged into the website. I did a bit of research and learned that there's no real way, or at least no easy way, to pull an image from a WebBrowser control. So I went about Load'ing it with a PictureBox until I found out that the manner in which the image is loaded doesn't retain the session cookie in the WebBrowser. Thus I ran into a rather large dilemma, I needed to load the image while remaining logged in and the PictureBox was definitely not the correct solution nor was trying to pull it out of the WebBrowser control.

I did quite a bit more research and came across the HttpWebRequest and the HttpWebResponse classes. I knew that if I could some how send out the correct cookie data from my WebBrowser control with my request for the image, I'd get what I wanted. So I quick parsed the cookie credentials from my WebBrowser control (which was a bit of a pain because they each have their different forms of storing the cookie information), added it to my request, and got my image perfectly.

Code:
HttpWebRequest h = (HttpWebRequest)WebRequest.Create(URL);
h.CookieContainer = new CookieContainer();

foreach (string Cooky in webBrowser.Document.Cookie.Split(';'))
{
    h.CookieContainer.Add(new Cookie(Cooky.Split('=')[0].Replace(" ", ""), Cooky.Split('=')[1].Replace(" ", ""), DOMAIN, URL));
}

HttpWebResponse response = (HttpWebResponse)h.GetResponse();
Stream simg = response.GetResponseStream();
Image bimg = new Bitmap(simg);


I posted this code at the CodeProject where a few people were looking to do the same thing.