RSS 2.0 Feed
RSS 2.0


Atom 1.0 Feed
Atom 1.0

  Using the Web Browser Control in your C# Applications 

It can be a powerful thing to display dynamic HTML in your C# applications. It can give your applications a modern look and feel and can make displaying data in non-standard ways easy with some simple markup. We have the web browser ActiveX control that wraps up what we know as Internet Explorer. While I don't want to get into the in's and out's of using the web browser in your applications, I do want to demonstrate a few things that will make the use of the web browser easier so you can integrate it seamlessly into your applications.

Some common requests I see in regards to using the web browser control is the ability to set the HTML to display in the browser without writing it to a file and navigating to it, printing the contents of the browser, and other items related to manipulating it's contents. Let's take a quick look at those.

Setting the HTML without writing to a file

Many times when the web browser control is used, the HTML content that the developer wishes to display will be written to a text/html file and then Navigate is used to navigate to the file, such as the following:

object empty = System.Reflection.Missing.Value;
axWebBrowser1.Navigate(@"c:\myfile.htm", ref empty, ref empty, ref empty, ref empty);

The problem with that is, of course, that you need to write to a file. This brings in other possible issues such as ensuring you write the file to a location where the user has permissions to do so. A better route is to not write to a file at all. Instead, set the HTML directly in the browser. To accomplish this we need to get a reference to the browser's internal HTML document and manipulate it using the Document Object Model. We need to add a reference to the “Microsoft HTML Object Library” (mshtml) to get to the interfaces & classes that we will use to get to the document's DOM. Once you add the reference, you can get to the document and do whatever you want. However, in order to get to the document, you will have to navigate to about:blank before it can be accessed. If you do not first load or navigate to something then the document will be null. So first of all let's load about:blank to create a blank document.

object empty = System.Reflection.Missing.Value;
axWebBrowser1.Navigate("about:blank", ref empty, ref empty, ref empty, ref empty);

Now that we've done that we can get a reference to the document's DOM via the IHTMLDocument interface and write to it.

// create an IHTMLDocument2
mshtml.IHTMLDocument2 doc = axWebBrowser1.Document as mshtml.IHTMLDocument2;

// write to the doc
doc.clear();
doc.writeln("This is my text...");

doc.close();

Not too bad. We can write whatever markup we want to the document such as HTML, links, CSS, or even JavaScript.

Printing the Browser content

With a reference to the document, we can do whatever we want with it. That would include methods in the DOM such as execCommand. We can use that to print the browser's HTML.

mshtml.IHTMLDocument2 doc = axWebBrowser1.Document as mshtml.IHTMLDocument2;
doc.execCommand("Print", true, 0);

Printing is only the beginning of what you can do here. Take a look at all the possible commands you can send via execCommand here. It really opens up what you can get to when you look at what you have available. I'll outline in another post how to disable the right-click menu of the browser (by default you'll get the standard IE right-click menu) as well as how to take this a step further in integrating the power of C# with dynamic HTML in your applications.




                   



Leave a comment below.

Comments

  1. Richard Poole 2/2/2005 4:21 AM
    Gravatar
    Hi Ryan,

    I've seen several methods for accomplishing this but I'm still looking for a way to include images in the rendered HTML without requiring them to be external files. I believe some web-based native applications (e.g. various Control Panel applets) use the res:// scheme to get the images from embedded resources within the .dll (or .cpl as the case may be), though to my knowledge this is not possible with a .NET assembly. I can think of two ways that might make this possible: -

    1. Implement a new URL moniker that catches your own custom URL scheme (like "application://Company.Application.Resources/Image1") and somehow make it read the binary image data from your managed resource DLL and return it to the WebBrowser control as if it had just 'downloaded' it from a file on the hard disk or from the web. URL monikers look unbelievably complicated for a task that I consider should be trivial, so I'm naturally inclided to avoid this approach.

    2. Subscribe to a WebBrowser event that is fired *before* it attempts to download the image via the URL monikers that will allow you to essentially implement an in-place URL moniker. I've looked and looked through the interfaces available and can't see any event that would allow this.

    They're probably both wrong, but I'm clutching at straws here.

    Any ideas?
  2. Programmer 2/8/2005 9:44 AM
    Gravatar
    does it describes how to get the url from the browser??
  3. inNeed 2/9/2005 6:16 PM
    Gravatar
    thanks so much! This really helped!
  4. inNeed 2/9/2005 11:38 PM
    Gravatar
    hey! everytime i start printing it doesn't print the whole thing. It prints one page of whatevers posted in the web browser, it doesnt continue it anymore. what could be the problem?
  5. Ryan Farley 2/15/2005 9:01 AM
    Gravatar
    inNeed,

    That doesn't happen for me. I loaded a long block on HTML - not all of it was visible in the window (ie: you had to scroll quite a bit to get to the end) and it all printed fine.

    Do you get the same behavior when just printing a page in IE?

    -Ryan
  6. Ryan Farley 2/15/2005 9:07 AM
    Gravatar
    Programmer,

    To get the URL from the browser all you need to do is get a reference to the document (as outlined in the post) and then read the "location" property.

    -Ryan
  7. Ryan Farley 2/15/2005 9:10 AM
    Gravatar
    Richard,

    Including images from your app's resources would be awesome! I could see it working by buildin a custom moniker. That would be cool - I'll have to give that one a shot.

    -Ryan
  8. bobby t. 2/25/2005 7:45 AM
    Gravatar
    thanks for the demo, it helped my understanding alot. I was wondering if we can retrieve the html just as easy as the writeln method. how can we access the source? (i'll be comparing the current source to the original html string).

    thanks!
  9. Ryan Farley 2/25/2005 8:49 AM
    Gravatar
    bobby,

    There's a few ways to get the HTML from the browser. An easy way is to read the innerHTML from the document's body:

    mshtml.IHTMLDocument2 doc = axWebBrowser1.Document as mshtml.IHTMLDocument2;
    MessageBox.Show(doc.body.innerHTML);

    -Ryan
  10. bobby t 2/25/2005 10:04 AM
    Gravatar
    tks for the response with the innerHTML property. But i was wondering if i can fetch the entire source including all <html><head><body> tags and javascript functions. I've also tried the outerHTML property and it only returns the body.

    thanks again.
  11. Joshua Rowe 2/28/2005 6:41 PM
    Gravatar
    Richard -

    I've come to similar conclusions, although the .mht file format might also be useful.

    I may end up using temporary files as the solution to my problem if I can't figure out the magic of .mht files.
  12. Dustin Lyday 3/3/2005 3:29 PM
    Gravatar
    I see what you are doing but what is this "mshtml" you are using. Where is all the COM implmentation behind it? I have to implement this myself very quickly so if you could respond quickly, I'd really appreciate it.
  13. happer 3/4/2005 10:00 AM
    Gravatar
    In response to an earlier question on how to get the entire source:

    You may have already figured this out but you can get the whole document source including all <head><body> tags by using the following:
    string source = ((mshtml.HTMLDocumentClass)(doc)).documentElement.innerHTML;

    Cheers
  14. happer 3/4/2005 10:13 AM
    Gravatar
    Sorry..should have been

    string source = ((mshtml.HTMLDocumentClass)(doc)).documentElement.outerHTML;
  15. Ryan Farley 3/7/2005 8:18 AM
    Gravatar
    Dustin,

    mshtml is implemented in a COM library that you will already have on your pc. Add a reference to the COM library named "Microsoft HTML Object Library". It will of course create the needed interop wrapper named mshtml.

    -Ryan
  16. Kumar 3/14/2005 2:58 PM
    Gravatar
    hi all
    i need to iterate through html source one by one using the web browser
    for that i hav to call my own function which captures the data
    can any one help me that how do i change the URL automatically and when that HTML is created so that i can get my function invoked ?
  17. Duong Minh Khoa 3/17/2005 1:11 AM
    Gravatar
    How do disable Popup menu on web browser control? Please show me the way. Thanks for your kindly.
  18. Brent B 3/21/2005 2:29 PM
    Gravatar
    Hi,

    I just tried writing dynamic html to the control that includes a input text box. I am unable to type in the edit box. If I load from a file using Navigate it works fine.

    Anyone else seen this? Is there a work-around?

    Thanks,

    Brent
  19. V 3/30/2005 10:18 PM
    Gravatar
    Hi

    I am using the webbrowser control in my application. Is there some way to set the internet proxy server in the browser control.

    Thanks
  20. Gal Bitton 4/11/2005 8:06 AM
    Gravatar
    Hi,
    I am using the webbrowser control in my application a bit differently-
    I opened the url automatically in the webbrowser.
    Then, I tried to print the page and the print dialog box opened through which I could print.
    Let's say I want to automate the all process, meaning, after opening the html page I will activate the print button from the software (with no user involvement). I want to skip the print dialog box.
    The command is : doc.execCommand("Print", true, 0);
    How can I print without going through the print dialog box?

    Thanks, Gal.

  21. Jose 4/13/2005 11:49 PM
    Gravatar
    Hi, how can i print a document html on background?
  22. Jose 4/14/2005 12:07 AM
    Gravatar
    Gail the solution to your problems come out.

    SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorerClass();
    SHDocVw.IWebBrowserApp wb = (SHDocVw.IWebBrowserApp) ie;
    wb.Visible = false;//if u want background printing
    object noValue = System.Reflection.Missing.Value;
    object noValue1 = System.Reflection.Missing.Value;
    ie.Navigate("about:blank", ref noValue, ref noValue, ref noValue, ref noValue);
    mshtml.IHTMLDocument2 htmlDoc2 = ie.Document as mshtml.IHTMLDocument2;

    // Update the document.
    htmlDoc2.clear();
    htmlDoc2.writeln("<font face=\"Arial\" size=2>Web browser demo. Visit <a href=\"http://www.ryanfarley.com/">http://www.ryanfarley.com/\" target=_blank>ryanfarley.com</a> for more.</font><br><br><a href=\"http://www.ryanfarley.com/">http://www.ryanfarley.com/\" border=0><img src=\"http://ryanfarley.com/Skins/RyanFarleyBlue2/Images/RyanFarley-Title_bg.jpg\" border=0></a>");

    ie.ExecWB( SHDocVw.OLECMDID.OLECMDID_PRINT,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,ref noValue,ref noValue1);
  23. P 4/22/2005 11:27 AM
    Gravatar
    Hey Ryan,

    Thanks for the great article.

    I was trying to do the navigating and the printing on the click of a button and therefore put the code together as:

    object empty = System.Reflection.Missing.Value;
    axWebBrowser1.Navigate(HTMLFile, ref empty, ref empty, ref empty, ref empty);
    mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2) axWebBrowser1.Document;
    doc.execCommand("Print", false, 0);

    But I always get a blank print out. Am I missing something here?

    Thanks
  24. P 4/22/2005 11:49 AM
    Gravatar
    Hey Jose,

    Your code segment looks interesting. But just a quick addition. Is there a way to print to a file where I specify the filename of the file to be created, within the code?

    Thanks
  25. Mukesh 4/25/2005 1:12 AM
    Gravatar
    Hi Rayn,

    I have been using the technique mentioned by your for printing HTML files, navigating to about:blank and then calling ExecWB.

    But the issue is that in the print spoller dialog box we see the name of file being printed as about:blank. Is there a way we could change this to a meaningful name?

    Regards,
    Mukesh
    mgupta@quark.co.in
  26. Ian Bugeja 4/25/2005 8:26 AM
    Gravatar
    i found something really weird,
    got a form which is maximised and added a tabcontrol with docking left, right, top and bottom

    when i add the navigation control to some tabpage the docking is lost

    any ideas?


    Regards,
    Ian Bugeja
    mr_ian84@hotmail.com
  27. Zeeshan Shakeel 5/9/2005 3:19 AM
    Gravatar
    Hi Ryan,
    Context : Invalid Cast Exception on casting IHTMLDocument to IDisplayServices Interface
    I am working upon an application that happens to host MSHTML.I am developing a component that provides "spell check as u type" services.
    I am having problem of "Invalid Cast Exception" . I will define the problem in the end. First the scenario is as follows,

    Spell Checking Stretgy :

    My stretegy as follows,

    I send browser text to a Spell Checking Engin. raises MissSpelledFound event whenever it encountered a incorrectly typed word along with all indexing info (means where it can be located in original string).
    Event Hanler that captures MiSpelledWordFound Event is as follows,

    private void spellChecker_OnMissSpelledWordFound(NetSpell.SpellChecker.SpellingEventArgs e)
    {

    mshtml.IDisplayServices ids = null;
    mshtml.IMarkupServices ims = null;
    mshtml.IMarkupPointer impStart;
    mshtml.IMarkupPointer impEnd;

    mshtml.IHTMLDocument doc = (mshtml.IHTMLDocument)this.axWebBrowser.Document;
    mshtml.IHTMLDocument2 doc2 = (mshtml.IHTMLDocument2)this.axWebBrowser.Document;
    mshtml.IHTMLDocument3 doc3 = (mshtml.IHTMLDocument3)this.axWebBrowser.Document;
    mshtml.IHTMLDocument4 doc4 = (mshtml.IHTMLDocument4)this.axWebBrowser.Document;
    mshtml.IHTMLDocument5 doc5 = (mshtml.IHTMLDocument5)this.axWebBrowser.Document;


    //Following lines doesn't type cast ot any of them; will alwasy return null
    //But this happenns only when I try to call th
    if(ids == null)
    ids = doc2 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc3 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc4 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc5 as mshtml.IDisplayServices;
    if(ids == null)
    return;


    ims = doc as mshtml.IMarkupServices;
    if(ims == null)
    ims = doc2 as mshtml.IMarkupServices;
    if(ims == null)
    ims = doc3 as mshtml.IMarkupServices;
    if(ids == null)
    ims = doc4 as mshtml.IMarkupServices;
    if(ids == null)
    ims = doc5 as mshtml.IMarkupServices;
    if(ims == null)
    return;


    ushort letter = ' ';

    mshtml.IHTMLElement newElement = null;
    ims.createElement(mshtml._ELEMENT_TAG_ID.TAGID_TT, ref letter,out newElement);
    //create markup pointers
    mshtml.IHTMLElement body = (mshtml.IHTMLElement)doc2.body;
    //get markup pointers
    ims.CreateMarkupPointer(out impStart);
    ims.CreateMarkupPointer(out impEnd);
    //locate markup pointers properly
    //set both start & end markup pointers at the start of body
    impStart.MoveAdjacentToElement(body,mshtml._ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
    impEnd.MoveAdjacentToElement(body,mshtml._ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
    //set markup pointers around missSpelled word
    for(int i=0;i<e.WordIndex;i++)
    {
    impStart.MoveUnit(mshtml._MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN);
    impEnd.MoveUnit(mshtml._MOVEUNIT_ACTION.MOVEUNIT_NEXTWORDBEGIN);
    }
    //now adjust impEnd
    for(int i=0; i<e.Word.Length;i++)
    impEnd.MoveUnit(mshtml._MOVEUNIT_ACTION.MOVEUNIT_NEXTCHAR);
    //insert elemetn here
    ims.InsertElement(newElement,impStart,impEnd);
    //underline the text
    this.Underline(newElement);//This is code written by Charles Law(Thankx 4 underlining code)


    }

    This method does its best, when I run it from any event which is not a Thread(Strictly saying this).
    But Whenever a background spell checking thread that I code to provide "check spell as u type" services, I then find similar problems as Misha that is


    mshtml.IHTMLDocument doc = (mshtml.IHTMLDocument)this.axWebBrowser.Document;
    mshtml.IHTMLDocument2 doc2 = (mshtml.IHTMLDocument2)this.axWebBrowser.Document;
    mshtml.IHTMLDocument3 doc3 = (mshtml.IHTMLDocument3)this.axWebBrowser.Document;
    mshtml.IHTMLDocument4 doc4 = (mshtml.IHTMLDocument4)this.axWebBrowser.Document;
    mshtml.IHTMLDocument5 doc5 = (mshtml.IHTMLDocument5)this.axWebBrowser.Document;

    ids = doc as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc2 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc3 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc4 as mshtml.IDisplayServices;
    if(ids == null)
    ids = doc5 as mshtml.IDisplayServices;
    if(ids == null)
    return;

    Problem :
    IHTMLDocument never typecast to IDisplay Services, this is the real trouble, I have not been able to cope with,
    When it happens, no underlyining can be done using IDisplayServices. At leasst I could not do so.( I wish If somebody can get me out of this problem).

    Can Somebody help me???

    Zeeshan Shakeel
    Software Developer
    Live Tech
    zee_shakeel@yahoo.com






  28. Justin 5/9/2005 4:33 PM
    Gravatar
    Is there anyway I can make a DIV in the browser programmatically so that I can display a SAMI file on top of it?

    Thanks,
    Justin
  29. Prasad 5/11/2005 1:53 AM
    Gravatar
    Hi All.,
    i am using mshtml for retrievel of page. and this to do this i need to login to that page by passng user,password. this taks also i can do.and am able to display the page in webbroser control on my form.now my requirement is i need to scrap the page contents which includes sub pages. how to handle this with mshtml. any idea..

    i appriciate for any help..

    thanks.,
    Prasad
  30. Slack 5/18/2005 12:28 PM
    Gravatar
    Hi, i have a question..........

    how can I manipulate de popups????

    I'm tryed to do mi webbrowser, but, when I open a link, this link go to the internet explorer, and there is open.

    the same is with de popus.

    can you helpme????
  31. Chris Rowe 5/18/2005 3:14 PM
    Gravatar
    Hi Ryan

    With regard to Richard Poole' post of the 2/2/2005, re: including images streamed to a bespoke browser app.

    I currently have a VB6, fat client, app that that renders a streamed serialized file, from a remote file share, that includes a jpeg image plus various text overlays which are configured by the user.

    In order to conform to http://www.section508.gov/IRSCourse/mod02/020301--.html and to provide a more up to date, accessible solution I'm very interested in being able to provide this via a custom browser app.

    Using a browser based app makes it very much easier to aline both the requirements of 508 and of the various screen readers that are available in the market. For me the base default is Microsoft's accessibility reader that comes with their various OS's.

    A browser based solution has tendency to be read in a more user friendly way, title tag, mouseover and alt tags etc, than a form based executable, which appears to require the user to give focus in order for the screen reader function.

    To this end I am interested in your comments of 2/15/2005 and wether you have had the time to further your research.

    Chris
  32. Larry Kamlot 5/20/2005 10:03 AM
    Gravatar
    Excellent. Very useful; a time saver. Larry K.
  33. Florin 5/21/2005 1:01 PM
    Gravatar
    How can I set the scroll bar to a AxWebBrowser control to bottom for a chat application?
  34. sabari 5/25/2005 8:40 PM
    Gravatar
    Hi
    How can i implement the same printing functionality in a web application where i cant use the webbrowser control . I actulay want to read some html content from the database and print it directly without any prompting.

    Please put in your suggestions
  35. Josh Blair 5/26/2005 3:43 PM
    Gravatar
    Ryan, this is a great sample and has generated quite a useful thread. Thanks for the information.

    I too am looking for a way to include images in the HTML that are embedded in a resource file. Any luck on that end?

    Thanks!

    Josh Blair
    http://joshblair.blogspot.com/
  36. stardawg 6/7/2005 12:36 PM
    Gravatar
    Hopefully this didn't double post, but here goes:

    To print without prompting the user, I use a windows form and add a web control to the designer named AxWebBrowser1. Then I use the following code to print an HTML file from a local directory:

    Private Sub PrintDocument(ByVal pDocument As String)
    Dim o As Object = System.Reflection.Missing.Value
    Dim url As String = "file:///" + pDocument.Replace("\", "/")

    Me.AxWebBrowser1.Silent = True
    Me.AxWebBrowser1.Navigate(url, o, o, o, o)

    Me.AxWebBrowser1.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER)

    End Sub


    The problem is I can't set the page/printer properties (i.e. orientation, margins, page size, copies, etc.) Any advise would be greatly appreciated.
  37. Help me 6/8/2005 10:03 AM
    Gravatar
    While printing from the browser I've noticed that on certain OS it doesn't print when you invoke the print command on 2000 or XP with sp1. I've read that there might be a issue with the SHDocVw.dll. Is this the case or is there some other reason. Here is my function call. This call prints on most of my OS.

    axWebBrowser1.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT,
    SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
    ref o, ref o);
  38. Priya 6/21/2005 1:23 PM
    Gravatar
    Any luck on getting the scroll to bottom work?
  39. Josh 6/22/2005 9:24 AM
    Gravatar
    Good article. Interesting thing I'm finding with using mshtml and the Web Browser control is that there is no indexing for any of the collections.

    I.E. - normally, to reference an item in the frames collection you'd have something like

    IHTMLDocument2 doc = (IHTMLDocument2) axWebBrowser1.Document;
    doc.frames("someframe").innerHTML;

    Seems like a minor obstacle, so I went around that lack of indexing and went to the trouble of using the HTMLFrameElement.item(ref ptrIndex) function to get the frame. That worked, but any time I attempt to access any property, a COM exception is thrown (devilishly hard to track down!!!):

    "Marshalling Restriction: Excessively long string"

    I haven't really seen any documentation on why this error comes about; I've even put in an unsafe code block and tried to marshall the return strings as different types of strings with no luck.

    This whole indexer thing is simply weird, and the Marshaller problem even weirder!
  40. Lalit Dubey 6/25/2005 4:10 AM
    Gravatar
    Hi All,

    I am using axWebBrowser control , and trying to display the full content of the page in a small window.
    I have added the control at pannel.

    Problem:
    1- when it added to a pannel it dont show the horijontal/vertical sliding bar.
    2- the content donr fit in that area. and thus all the content of the page is not visible.

    Point pt=new Point(0,0);
    axWebBrowser1.Resizable=true;
    axWebBrowser1.Parent=this.panel1;
    axWebBrowser1.Size=panel1.Size;
    axWebBrowser1.Location=pt;
    string objlocation="http://www.google.co.in/";
    object empty=System.Reflection.Missing.Value;

    axWebBrowser1.Navigate(objlocation, ref empty,ref empty, ref empty,ref empty);


    can we stretch to fit the exploral windoe in some certain area ?
    Please help me out here.

    Thanks in advance .

    Please reply me : ldubey@digisigntech.com

    Regards,
    Lalit Dubey
    AT DigisignTechnologies Noida,

  41. Ryan 6/27/2005 6:30 AM
    Gravatar
    Great article Ryan -- very helpful.

    Can anyone point me in the right direction to figure out how to "paint" (pixel by pixel) right on top of the surface of a web page loaded in IE? I'm talking about going beyond what is possible by adding elements to the DOM and just adding graphics right on top of the web page. Any ideas?

    Thanks!
    Ryan
  42. Robb Force 7/6/2005 1:23 PM
    Gravatar
    "The problem is I can't set the page/printer properties (i.e. orientation, margins, page size, copies, etc.) Any advise would be greatly appreciated."

    The printer properties are the same as IE and are stored in the registry. The easiest way to deal with this is have your code check the values and set the values you want during installation or everytime your app is run.
  43. Mohammed Raheem 7/25/2005 3:55 AM
    Gravatar
    I am looking for the code to stretch the website contents to the size of webbrowser control . so that i show all the contents at time.
  44. chava 7/25/2005 1:03 PM
    Gravatar
    Hi ,
    I am trying to write an extension to IE,trying to tranlate the english text to indic script. I need to get the text as the user enters in a text area in a form and then convert it to unicode. how can i get the text or keyboard input. I thought of hooks but i dont want to use hooks because they need global resources and it gets messy.
    thanks
    chava
  45. fi 7/28/2005 6:35 AM
    Gravatar
    Hi there,

    I'm having some trouble implementing your code. If I download your example it works fine, but I'm trying to incorporate it as follows:

    private void Form1_Load(object sender, System.EventArgs e)
    {

    startUpURL = ConfigurationSettings.AppSettings["StartUpFile"];

    object vHeaders;
    object oEmpty = "";
    object oURL=startUpURL;
    vHeaders = "Content-Type: application/x-www-form-urlencoded" + "\n" + "\r";
    axWebBrowser1.Navigate2(ref oURL, ref oEmpty, ref oEmpty, ref oEmpty, ref vHeaders);
    }

    private void axWebBrowser1_BeforeNavigate2(object sender, AxSHDocVw.DWebBrowserEvents2_BeforeNavigate2Event e)
    {
    string strURL = e.uRL.ToString();

    if (strURL.StartsWith("prereqcheck"))
    { {
    e.cancel = true;


    //some other code here

    //write to the HTML directly
    object empty = System.Reflection.Missing.Value;
    object oURL="about:blank";
    axWebBrowser.Navigate("about:blank", ref empty, ref empty, ref empty, ref empty);

    //create an IHTMLDocument2
    mshtml.IHTMLDocument2 doc = axWebBrowser1.Document as mshtml.IHTMLDocument2;

    // write to the doc
    doc.clear();

    doc.writeln("<HTML>This is my text...</HTML>");

    doc.close();
    }
    }

    However after it executes "doc.Close()", the WebBrowser control shows a blank document. Any ideas why this is happening?

    Thanks,
    Fi
  46. Ramesh 7/30/2005 6:18 AM
    Gravatar
    Ryan,

    Thanks for this immensely useful article. Have you posted your next article on disabling the context menu ?

    Thanks.
  47. Wade 8/9/2005 8:24 PM
    Gravatar
    Is there a way to access the current browser that is open? I have a web app where I want to access the DOM but I am not using a activex control for browsing. Just the default browser that it pops up in when I run the app. How do I access that?
  48. ruben 8/10/2005 2:36 AM
    Gravatar
    Hi fi,

    You must execute the code of BeforeNavigate2 event on the NavigateComplete2 event. Before, you must capture the url on the BeforeNavigate2 event, and, for example, write this url in a property to can access to the url in NavigateComplete2 event.
  49. sath 8/24/2005 10:15 PM
    Gravatar
    Hi Ryan,

    You had mentioned that you will show how to disable right click menu of a browser hosted inside a control. can you let me know

    cheers
  50. Jamie 9/13/2005 8:14 AM
    Gravatar
    Super little article - thank you. Was just what I needed! Small but perfectly formed. :-P
  51. Raj 9/16/2005 6:08 AM
    Gravatar
    Hi Ryan,

    I am using this AXWebBrowser control in a winform application, but i experienced that the html page is not accepting any keyboard input for any text boxes in there. Can you please tell me where i have gone wrong or how to fix this issue. Thanks for your help.

    -Raj
  52. glyn 10/21/2005 1:32 AM
    Gravatar
    Hi Ryan,

    nice artical - however, I think it does not go far enough in exploring what windows client developers are requested to develop - i.e more clients which can read html / xml data (smart?)

    Any article on this subject which would be useful should include:

    how to print preview - print
    how to input html / xml data
    how to read html / xml data - user input
  53. Pushkar Modi 10/21/2005 4:34 AM
    Gravatar
    How can we implement a PageSetupDialog for the Web Control?
  54. randall 11/11/2005 11:31 AM
    Gravatar
    I'm looking at writing a c# app to drive a web application I need to test. I have the browser control setup and have some rudementary navigation happening, but I've run into problems.

    The html of the pages I'm navigating isn't very good and many of the tags don't have a name or id attribute, making them tough to get at in my app. I've been able to get around this using the innerHTML and innerText properties to match on known values, but I just hit a new snag.

    I guess the method of accessing the DOM breaks down if it hits a nested table. I was having trouble matching a known innerText value so I had the app spit out all of the tags it was examining. It gets to a table tag nested within another table tag and stops processing tags.

    Anyone have any ideas, or links specifically abount navigating the DOM? thanks in advance!
  55. glyn 11/28/2005 2:45 AM
    Gravatar
    (I know VB.NET) ... but what the hell...most of the problems (questions presented here) can be solved by searching google, and looking at the MSDN web site. I found that the Microsoft .NET (VS 2003) way of wrapping this control did not work properly as there is a bug ... (handle click events get un-handled after navigating using the control) after much searching a Microsoft person on a non Microsoft web site agreed and said go back the old VB6 wapper method (which was posted on the VB Xtream forum).

    I hope this helps someone who like me has had to rewire there app due to this interesting control.
  56. tracernet 11/28/2005 6:41 AM
    Gravatar
    good day....

    this i one hell of a tutorial...!!!! i really liked it... :D

    any way.... i just want to ask about how to get the title of the web page i had just accessed...

    the codes

    mshtml.IHTMLDocument2 ihtdoc2 = this.axWebBrowser1.Document as mshtml.IHTMLDocument2;
    this.richTextBox1.Text = ihtdoc2.body.innerHTML;


    doesnt seem to help...

    thanks....
  57. Alex007 11/29/2005 8:29 AM
    Gravatar
    Hi there,
    Thanks to Ryan for is great sample and to the every bodywho animqte the discuss around the subject.

    I have a question, i need to change the print Page setup in the code, wihtout display the interface, Directely i need to change the marginLeft to 0 before to use the WebBroser for the printing

    this.axWebBrowser1.Silent = true;
    axWebBrowser1.Navigate("about:blank", ref empty, ref empty, ref empty, ref empty);
    axWebBrowser1.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
    ref empty, ref empty);

    Somebody has an idea?????

    Thanks
  58. Arun Appukuttan 12/1/2005 12:05 AM
    Gravatar
    HI ALL,

    I have placed a WebBrowser in a Form(C# language) and navigated to a website. Then i have an another application which sends keystrokes to the form containing WebBrowser.
    if we use
    SendKeys.Send({A}); //not working
    ////////
    SendKeys.Send({TAB}); //WORKING
    SendKeys.Send(+{TAB});
    SendKeys.Send({A});
    my email is :arun5_appu@yahoo.com

    Thank You
    Arun Appukuttan


  59. Alex007 12/1/2005 6:03 AM
    Gravatar
    Hi there,

    I need to print the contains on my webbroser, i have 12 lines, and when i print, the document had 60 lines that means 48 blank lines. I don't known how to size the numbers of lines to print. This is my command:
    axWebBrowser1.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref empty, ref empty);


    Thanks.
  60. Carlos 12/2/2005 7:27 AM
    Gravatar
    I'm also struggling to find a way to programatically change the Printing properties (margins, header, footer)... anyone had any luck doing that?
  61. Arun Appukuttan 12/6/2005 8:36 PM
    Gravatar
    HI ALL,

    I have placed a WebBrowser in a Form(C# language) and navigated to a website. Then i have an another application which sends keystrokes to the form containing WebBrowser.
    if we use
    SendKeys.Send({A}); //not working
    ////////
    SendKeys.Send({TAB}); //WORKING
    SendKeys.Send(+{TAB});
    SendKeys.Send({A});
    my email is :arun5_appu@yahoo.com
    Can anybody help me in this matter(ie why WebBrowser not receiving keystrokes)


    Thank You
    Arun Appukuttan
  62. ajith nair 12/13/2005 5:58 AM
    Gravatar
    i have embedded a webbrowser into a panel in C# project but getting a error that states that it could not find respective resource filename in the assembly file.As i am adding the webbrowser in panel so i m passing form name to resource manager ,i m getting runtime exception
  63. Damnish.kumar@hytechpro.com 12/16/2005 3:16 AM
    Gravatar
    This is good. But there is an issue with browser control print, it always use default printer to print, by no mean we can set the priting to any non default printer.
    Any clue from some one ?
  64. willstay 12/25/2005 8:06 PM
    Gravatar
    Can anyone tell me how to use Proxy with Web Browser Control? Can WebProxy combine with WebBrowserControl?
  65. Ryan Farley 12/25/2005 9:13 PM
    Gravatar
    willstay,

    The Web Browser control is just an embedded IE window. I believe any settings in IE (such as proxy settings) are honored just the same as they are in IE.

    -Ryan
  66. willstay 12/25/2005 10:21 PM
    Gravatar
    Ryan,

    Thanks for the reply. You are correct. It uses proxy settings that I have set through IE. But I was trying to set proxy from withing my code. The first option that hit me was by importing wininet.dll. All is fine for setting simple options but for setting Proxy, there is structure INTERNET_PROXY_INFO which has LPCTSTR members. I can simply use 'int' type replacing 'DWORD' but no idea for pointer to string in C#.

    typedef struct {
    DWORD dwAccessType;
    LPCTSTR lpszProxy;
    LPCTSTR lpszProxyBypass;
    };

    I found two ways of importing wininet.dll as I have listed below.

    [DllImport("wininet.dll", SetLastError = true)]
    private static extern bool InternetSetOption(IntPtr hInternet,
    int dwOption,
    IntPtr lpBuffer,
    int lpdwBufferLength);

    [DllImport("wininet.dll", CharSet=CharSet.Auto)]
    public static extern Int32 InternetSetOption(IntPtr hInternet,
    int dwOption,
    [In,Out] byte [] buffer,
    int BufferLength);

    and I am trying to make following line of code work.

    InternetSetOption(IntPtr.Zero, 38, some structure, Marshal.SizeOf(some structure));

    Any help would be highly appreciated.
  67. willstay 12/26/2005 1:44 AM
    Gravatar
    I figured it out finally. It took me hours of hit and trial to figure out methods to convert structure into proper form to pass to InternetSetOption method.


    Public struct Struct_INTERNET_PROXY_INFO
    {
    public int dwAccessType;
    public IntPtr proxy;
    public IntPtr proxyBypass;
    };

    [DllImport("wininet.dll", SetLastError = true)]
    private static extern bool InternetSetOption(IntPtr hInternet,
    int dwOption,
    IntPtr lpBuffer,
    int lpdwBufferLength);

    private void RefreshIESettings(string strProxy)
    {
    const int INTERNET_OPTION_PROXY = 38;
    const int INTERNET_OPEN_TYPE_PROXY = 3;

    Struct_INTERNET_PROXY_INFO struct_IPI;

    // Filling in structure
    struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
    struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy);
    struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi("local");

    // Allocating memory
    IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));

    // Converting structure to IntPtr
    Marshal.StructureToPtr(struct_IPI, intptrStruct, true);

    bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, Marshal.SizeOf(struct_IPI));
    }

    private void SomeFunc()
    {
    RefreshIESettings("1.2.3.4:8080");
    //or RefreshIESettings("http://1.2.3.4:8080"); //both worked
    //or RefreshIESettings("http=1.2.3.4:8080"); //both worked

    System.Object nullObject = 0;
    string strTemp = "";
    System.Object nullObjStr = strTemp;
    axWebBrowser1.Navigate("http://willstay.tripod.com", ref nullObject, ref nullObjStr, ref nullObjStr, ref nullObjStr);
    }
  68. VeN0m 12/29/2005 12:58 PM
    Gravatar
    Arun Appukuttan, use SendWait rather than Send
  69. Jill 1/7/2006 4:26 AM
    Gravatar
    hi all there
    i wanna help..i m trying to open a web page onclick event of a button when the page gets displayed in axwebbrowser control.
    problem is page gets displayed as a seprate window but i want it to open in the same (parent) window..any ideas
    thanks,
    Jill
  70. jugendra singh 1/11/2006 1:10 AM
    Gravatar
    Hello Sir,
    I am using axBrower with exccommand ("Print",true.0)
    It shows dialougebox but i do not want it.How can we solve this problem.
  71. Vijay 1/11/2006 8:41 AM
    Gravatar
    Hi I'm not able to view the html contents, it does not complain of any error. The form I'm opening is an MDI child.
    can u please suggest me how I can work around this.

    Regards
    Vijay
  72. Arun Appukuttan 1/12/2006 1:07 AM
    Gravatar
    Dear Ryan

    Using SendKeys.Sendwait() fn is not solving the webbrowser problem. This Problem persists in all Microsoft languages like(VB6,VB.Net,C#.Net).
    In MFC application this problem is not there. This problem is causing a lot of trouble to me.Please help me in this regard.

    Thank You in Advance
    Arun Appukuttan
  73. Anand 1/14/2006 1:55 AM
    Gravatar
    Hi,
    Does anyone have any idea on how to stream xml data(no xsl transformation to be applied) to an AxWebBrowser, without saving it on disk. I have tried using persistentStreamInit.Load() to send a stream, but it doesnt work.

    Thanks in advance for any help given.
  74. Adnan Siddiqi 1/25/2006 5:25 AM
    Gravatar
    nice article i must say,i did learn how to write HTML without writing in a File but i want to capture click event and perform some action that is on clicking a link i can capture the Inner HTML of some DIV etc

    is it possible?

    Thanks
  75. Adnan Siddiqi 1/27/2006 12:44 AM
    Gravatar
    Many of you will be aware of our mighty Webbrowser Control and would have used in different languages...
  76. david 2/9/2006 1:43 AM
    Gravatar
    Hello!

    I am showing a very simple example how-to change a IE proxy settings! (answer to willstay). The code works with no problem on win 2000 SP4.

    Greetings!!

    code:

    Private Sub ChangeIESettings(ByVal strProxy As String, ByVal action As Boolean)

    Dim RegKey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Internet Settings", True)
    ' to enable and set proxy in IE to variable strProxy
    ' the string is in format 'IPofProxy:port' --> '192.168.1.1:8080'
    ' or 'NAMEofProxy:port' --> 'proxyserver.com:8080'
    ' and action variable is true
    ' to disable use of proxy, set action to false
    If action = True Then
    RegKey.SetValue("ProxyServer", strProxy)
    RegKey.SetValue("ProxyEnable", 1)
    Else
    RegKey.SetValue("ProxyEnable", 0)
    End If

    End Sub
  77. Saps 2/13/2006 9:50 PM
    Gravatar
    Hi

    I have a large html file of several pages and would like to print a single page on which some kind of marking has been done..

    Is it possible to get the marked page and print that particular page.Also ie has no options to print the current page..

    Any Help Appreciated..

    Thanks..

    Saps
  78. Amit Bhandari 2/18/2006 4:32 AM
    Gravatar
    thanks for such a good article but i wonder how can one stop pop-up windows by using the web browser control in c#??
  79. Achar 2/21/2006 8:28 PM
    Gravatar
    Hi, I want to know if there is a way to merge contents from two or more Html files and display the same in the webbrowser control.
  80. David 2/28/2006 4:10 AM
    Gravatar
    If you want to use this technique in a loop, i.e. show a few pages, then remember to add a 'refresh' after each doc.writeln, i.e:

    doc.execCommand("Refresh", false, null);

    - David
  81. Richard 3/1/2006 11:49 AM
    Gravatar
    How can I draw to the webbrowser control (in the control) so that as I scroll the graphics will stay in the position in which it is drawn.

    A similar question was raised about halfway down on this forum, however I cannot see any answers.

    Thanks
    Richard
    email: rhwilburn <at> hotmail (dot) com
  82. Sanyok 3/16/2006 4:50 PM
    Gravatar
    About change proxy settings: there seems to be a big hidden caveat.

    If you use InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY,...), you switch global proxy settings for full environment. For many applications it's unsuitable. You need to transmit HINTERNET handle of session to InternetSetOption to switch settings for application, but that's appropriable only if InternetOpen()/etc. functions were used for connections. ActiveX control (shdocvw.dll), and, of course, wrapper System.Windows.Forms.WebBrowser, that appear in .NET Framework 2.0, doesn't give HINTERNET handle. We can't ever say that they use this method.

    Another way that was proposed on thread - modify registry - has the same problem. It affects whole user environment.
    If you implement IDocHostUIHandler interface (of course in class that also implement IOleClientSite and assign that client site to browser using browser.SetClientSite()), you will be able to switch path where IE will take settings for application:
    void IDocHostUIHandler.GetOptionKeyPath(out string pchKey, uint dw)
    {
    pchKey = "Software\\TestTest";
    }
    but it looks like IE doesn't try to look for proxy settings there. Many other settings can be configured, but not proxy one...
    Question is: how MyIE guys do this?? Or no one uses ActiveX in production the same way as we are? Or Everyone is happy with good old IE settings?
  83. Bill 3/28/2006 4:41 AM
    Gravatar
    I've run into a similar problem as mentioned above. How do I set Customized Proxy Settings for a specific webbrowser control? I've tried using:

    IDocHostUIHandler.GetOptionKeyPath
    and
    IDocHostUIHandler2.GetOverrideKeyPath

    but neither one of these seems to work. Is it not possible to have a specific webbrowser control access the internet thru a proxy while leaving the regular connection to the internet alone for all other instances of IE?
  84. Qaiser Mehmood Mughal 3/31/2006 1:25 AM
    Gravatar
    Hey Ryan,

    Very helpfull article.

  85. Qaiser Mehmood Mughal 3/31/2006 1:30 AM
    Gravatar
    Hey,
    I need some help from u peoples .
    I am using a web browser control in my window's application and its working fine, but i need to draw a rectangle on opened document using mouse.

    same as some screen capturing softwares do.
    so how can i do this help please.
    thank you in advance.
  86. Mariam 4/14/2006 11:04 PM
    Gravatar
    Hi ,

    i was browsing through your posts and i realized that you might be able to help me with a problem i m having while coding in c++.

    I'm developing an application in C++ that extracts each sentence dispalyed in a browser, translates it and then displays the translation in the webpage.

    I am using IHTMLDocument2 to do this. When the translated text is complete I write it to the browser using IHTMLDocument2::write(), and I can see the whole of the translated text.

    I want to change this so that I can display the translation of each sentence as I receive it. I tried doing this by using IHTMLDocument2::write() for each sentence and then calling:

    IHTMLDocument2::execCommand(bstr2, false, pVar, NULL);
    IHTMLDocument2::close();

    where
    BSTR bstr2 = SysAllocString((BSTR)L"Refresh");

    and
    VARIANT pVar={0};

    This does not work, I only see the complete translated text in one go at the end, not one by one as I need.

    If I put in a MessageBox after each write(), I am able to see the sentences displayed one by one, after I click OK on the MessageBox each time. But if there is no MessageBox I am not able to see the text appear incrementally.

    How can I make text appear incrementally on the browser as I write it to IHTMLDocument2?

    Any suggestion will be appreciated,
    Thank you.
  87. george a. 4/18/2006 3:18 AM
    Gravatar
    hi ryan,

    can you take a look at my code. im trying to fill a text box in a webpage that ive loaded in my browser control. but it update it. the attribute does get set though because the on the second click the is see the correct value. only it doesnt write on the textbox in the page like i want it to.
    heres the code:

    mshtml.HTMLDocument doc = (mshtml.HTMLDocument)this.axWebBrowser1.Document;

    mshtml.IHTMLElementCollection elem = (mshtml.IHTMLElementCollection)doc.body.all;
    mshtml.IHTMLElement mynode = (mshtml.IHTMLElement)elem.item("BXusername",0);

    string myapp1 = mynode.getAttribute("BXusername",0).ToString();
    this.textBox1.Text = myapp1.Trim();
    //(doc.body as mshtml.IHTMLElement3).contentEditable = "true";



    mynode.setAttribute("BXusername","skipper",1);
  88. Jake 4/20/2006 12:48 PM
    Gravatar
    Hi Ryan,
    GREAT JOB!
    I tyied your code on WinXP, worked fine; but it crashed on Windows Server 2003.

    "Application has generated an exception that could not be handled."

    It's got to be a security setting on Windows Server 2003....
    Has anyone got it to work?
    Thanks.
    Jake
  89. Ryan Farley 4/20/2006 1:25 PM
    Gravatar
    Jake,

    I have this working on Win2003 Server machines without issue. Did you get a specific error message or something?

    -Ryan
  90. Jake 4/21/2006 6:11 AM
    Gravatar
    I replyed to your message but I don't see it???
  91. jag 5/5/2006 9:33 AM
    Gravatar
    is their way to click on IE body. I am having this problem, I enter some text in textbox then i have to enter or tab to other part of IE to show this check box. please help
  92. james 5/23/2006 9:44 PM
    Gravatar
    hey ryan,

    it's quite a useful thread. Great work. hats off !!!!!

    but i dont know why no replies has been post on the problem regarding setting the print properties through code.


  93. Nafise salmani 5/30/2006 12:14 AM
    Gravatar
    hi

    it was really helpful, but there are some images in my htm Doc that when the webbrowser load that pages, their images didnt show!!

    could u help me please?
  94. Nafise salmani 5/30/2006 12:50 AM
    Gravatar
    hi

    it was really helpful, but there are some images in my htm Doc that when the webbrowser load that pages, their images didnt show!!

    could u help me please?
  95. fabio 6/1/2006 2:00 AM
    Gravatar
    hi,
    how i can attach to webBrowser object, an internet page that is open on the desktop???
  96. fabio 6/1/2006 2:06 AM
    Gravatar
    Hi, my name is fabio

    is possible to attach an IEXPLORE process to webBrowser object?

    sorry for the my english!

    thank's fabio!
  97. Ryan Farley 6/1/2006 6:50 AM
    Gravatar
    fabio,

    Not sure exactly what you're after, but if you want to "attach" to an open IE window then you'd want to use IE automation to do that. Google for "InternetExplorer.Application" and you're bound to find some good examples of that.

    -Ryan
  98. JonnyWee 6/2/2006 1:07 PM
    Gravatar
    Very helpful posts, great thread! Thanx, especially willstay for figuring out the proxy settings.
  99. fabio 6/6/2006 7:36 AM
    Gravatar
    hi Ryan,

    i now have open a IEPage in this method :
    foreach (SHDocVw.InternetExplorer ietemp in shellWindows )
    {
    ie = ietemp;
    ....
    break;
    }


    the next question is:
    how i can to recover a tag (<span > ) in ie.Document???
    how i can parsering the ie.Document???
    how i can to recover a javascript variable in ie.Document???


    thank's Fabio!

  100. Ryan Farley 6/6/2006 7:55 AM
    Gravatar
    fabio,

    From there it is just a matter of reading the HTML and parsing out the items you need. Use some regular expressions or I am sure you could find a library out there that parses out html elements also.

    Good luck.
    -Ryan
  101. Razi 6/7/2006 10:22 AM
    Gravatar
    How does one refer to a local file when using the file option?

    For example, if I use an IMG tag such as:

    <img src="myimage.gif"/>

    I get a missing image icon.

    I am