Click here to Skip to main content
11,641,971 members (61,522 online)
Click here to Skip to main content

Using MSHTML Advanced Hosting Interfaces

, 25 Jun 2002 496.7K 4.8K 144
Rate this:
Please Sign up or sign in to vote.
This article shows you how to use the Advanced Hosting Interfaces such as IDocHostUIHandler
<!-- Download Links -->

Overview

This article shows you how to use the MSHTML Advanced Hosting Interfaces, specifically IDocHostUIHandler, from .NET. These interfaces allow you very fine control over the user interface presented by the Microsoft Web Browser Control, for example, you can show your own context menu. I'll show you an easy way to use this interface without having to re-write the interface definitions yourself. As a bonus, I'll show you how to receive events from elements in the document.

The Problem

It is easy enough to put a web browser control on a form and get a fully-functional browser right away. But in your application, you might want finer control over how the control interacts with the user. For example, the standard IE context menu does not look particularly nice when you application shows an ultra-cool DHTML-based user interface. An interface called IDocHostUIHandler affords you this level of control.

Implementing IDocHostUIHandler

IDocHostUIHandler has to be implemented by your application. You can then use ICustomDoc::SetUIHandler to tell MSHTML that you have this interface.

IDocHostUIHandler is defined in MsHtmHst.idl in the Internet Development SDK, part of the Platform SDK. One approach I've seen is to do the import by hand - write the interface definition yourself in your source code.

The other approach, the one I'm going to use, is to create a type library with the interfaces we need declared in it, and then use the tlbimp tool to create an Interop assembly. No fiddling with marshalling yourself.

The first step would be to create an IDL file with the interfaces we need declared in it. You shall also need a UUID for the generated type library. There are only a few interfaces we need, and the entire IDL becomes:

MsHtmHstInterop.idl

[
    uuid(47F05070-FD66-45cc-AD99-74260F94A16B)
]
library MsHtmHstInterop
{
    import "MsHtmHst.idl";
    
    enum tagDOCHOSTUIDBLCLK;
    enum tagDOCHOSTUIFLAG;
    enum tagDOCHOSTUITYPE;
    
    interface ICustomDoc;
    interface IDocHostShowUI;
    interface IDocHostUIHandler;
    interface IDocHostUIHandler2;
    interface IHostDialogHelper;
};

I've included all the Advanced Hosting interfaces and enumerations here.

The next step is to generate the type library. Just compile the IDL file to get a TLB, using the Platform SDK tool MIDL.

midl MsHtmHstInterop.idl /tlb bin\MsHtmHstInterop.tlb

Now we need an interop assembly. We just have to use tlbimp on the newly created TLB file:

tlbimp bin\MsHtmHstInterop.tlb /out:bin\MsHtmHstInterop.dll

Now we can use the interfaces we need with just a using statement in our C# code:

HtmlUI.cs (partial)

using MsHtmHstInterop;

Wiring up

For the sample application, I have put just a single web browser control on a form. The form class implements IDocHostUIHandler.

To hook up the interface to MSHTML, we first need to get the ICustomDoc interface, and then call the SetUIHandler method with our interface as an argument.

HtmlUI.cs (partial - HtmlUIForm constructor)

public HtmlUIForm()
{
    InitializeComponent();
            
    this.WebBrowser.DocumentComplete += 
          new DWebBrowserEvents2_DocumentCompleteEventHandler(this.WebBrowser_DocumentComplete);
            
    object flags = 0;
    object targetFrame = String.Empty;
    object postData = String.Empty;
    object headers = String.Empty;
    this.WebBrowser.Navigate("about:blank", ref flags, ref targetFrame, 
                             ref postData, ref headers);
            
    ICustomDoc cDoc = (ICustomDoc)this.WebBrowser.Document;
    cDoc.SetUIHandler((IDocHostUIHandler)this);
            
    this.WebBrowser.Navigate(@"res://HtmlUI.exe/Sample1.htm", ref flags, ref targetFrame, 
                             ref postData, ref headers);
}

That's all there is to it. Of course, the form class implements the IDocHostUIHandler member functions.

HTML files in resources

You'll notice that I've used the res: protocol in my code. This is a neat way to package your HTML files and other support files - they're in the EXE itself. There are several advantages to this approach: your users cannot easily change the application's user interface, and you don't have to bother with packing more files into your install package.

You just have to make an RC file defining the resource:

HtmlUI.rc

Sample1.htm HTML "Sample1.htm"

This can then be compiled to get a RES file. You can add the RES file to your assembly with the /win32res C# compiler switch.

Handling Document Events

If your application has a DHTML-based user interface, you would definitely need to catch events from elements on the page in order to make it functional. If you run the sample app, you can see that clicking the button on the page shows you a message box. This message box has been invoked from the C# app, not from any scripts on the page. Here's the code:

HtmlUI.cs (partial)

private void WebBrowser_DocumentComplete(object sender, 
                                    AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
    // Get the document.
    IHTMLDocument2 doc = (IHTMLDocument2)this.WebBrowser.Document;
    
    // Get a reference to the button.
    HTMLButtonElement button = (HTMLButtonElement)doc.all.item("theButton", null);
    
    // Attach the event handler with the events interface.
    ((HTMLButtonElementEvents2_Event)button).onclick += 
                   new HTMLButtonElementEvents2_onclickEventHandler(this.Button_onclick);
}
        
private bool Button_onclick(IHTMLEventObj e)
{
    MessageBox.Show("Alert from the app: Received theButton.onclick!");
    return true;
}

Building the app

I have included a makefile which you can use to build from the command prompt. Just use nmake all to build the app. Note that the tlbimp mshtml.tlb step takes a while.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Nikhil Dabas
President NikSci
India India
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionTranslateAccelerator for keyboard inputs Pin
Florian Leitgeb23-Sep-13 4:00
memberFlorian Leitgeb23-Sep-13 4:00 
AnswerRe: TranslateAccelerator for keyboard inputs Pin
Florian Leitgeb23-Sep-13 5:52
memberFlorian Leitgeb23-Sep-13 5:52 
QuestionDrag a control item to webbrowser Pin
likui06239-Apr-13 22:38
memberlikui06239-Apr-13 22:38 
QuestionCleanly closing MSHTML without resource leaks Pin
tom_8556724-Jan-10 6:24
membertom_8556724-Jan-10 6:24 
GeneralTrack web browser requests Pin
Radu_2021-Oct-09 20:24
memberRadu_2021-Oct-09 20:24 
Generalradio button casting error Pin
faithfoxy11-Apr-09 22:00
memberfaithfoxy11-Apr-09 22:00 
hi everyone. i m using System.Windows.Forms.WebBrowser webbrowser1. and i try to get a radiobutton from page.
same page i could achieve this one.

IHTMLDocument2 doc = (mshtml.IHTMLDocument2)((mshtml.HTMLDocumentClass)wb1.Document.Window.Frames["frame"].Document.Forms["form1"].Document.DomDocument);

IHTMLSelectElement combo = (mshtml.IHTMLSelectElement)doc.all.item("comboBox",Missing.Value);

combo.selectedIndex = 8;
but at same page different time , i try to get

IHTMLDocument2 doc = (mshtml.IHTMLDocument2)((mshtml.HTMLDocumentClass)wb1.Document.Window.Frames["frame"].Document.Forms["form1"].Document.DomDocument);


IHTMLButtonElement elemen = ((mshtml.IHTMLButtonElement)doc.all.item("radiobutton",null));

but i get casting error. what is my mistake?

thanks.

Faith
GeneralProblem in getting source html code of last navigating page Pin
ravishankar_10-Mar-09 1:38
memberravishankar_10-Mar-09 1:38 
QuestionNice article, but have one question Pin
Radu_2017-Dec-08 0:58
memberRadu_2017-Dec-08 0:58 
AnswerRe: Nice article, but have one question Pin
Nikhil Dabas17-Dec-08 5:13
memberNikhil Dabas17-Dec-08 5:13 
QuestionAccess denied error Pin
10164-Sep-07 1:36
member10164-Sep-07 1:36 
GeneralMSHTML Error Pin
Quyen Pham Ngoc21-May-07 17:23
memberQuyen Pham Ngoc21-May-07 17:23 
Questiondetect popup window or message box. Pin
Renecito10-Oct-06 5:55
memberRenecito10-Oct-06 5:55 
QuestionCreating new Label or button control on web page at runtime Pin
ankur.ag198116-Jul-06 19:47
memberankur.ag198116-Jul-06 19:47 
AnswerRe: Creating new Label or button control on web page at runtime Pin
Nikhil Dabas16-Jul-06 20:37
memberNikhil Dabas16-Jul-06 20:37 
Questioninput fields disabled Pin
sb00014-Sep-05 22:13
membersb00014-Sep-05 22:13 
AnswerRe: input fields disabled Pin
A.J.Gibson8-Feb-06 7:49
memberA.J.Gibson8-Feb-06 7:49 
Questionhow to make a command line ? Pin
euioa20003-Sep-05 22:27
membereuioa20003-Sep-05 22:27 
GeneralGet XML from AxWebBrowser control Pin
Armoghan Asif3-Aug-05 1:44
memberArmoghan Asif3-Aug-05 1:44 
GeneralEvents are lost when more than one browser object Pin
simonclark3-Aug-04 4:16
membersimonclark3-Aug-04 4:16 
GeneralRe: Events are lost when more than one browser object Pin
simonclark4-Oct-04 23:56
membersimonclark4-Oct-04 23:56 
GeneralRe: Events are lost when more than one browser object Pin
Gashman24-Jun-05 6:57
memberGashman24-Jun-05 6:57 
GeneralRe: Events are lost when more than one browser object Pin
Armoghan Asif3-Aug-05 1:39
memberArmoghan Asif3-Aug-05 1:39 
GeneralDrag/Drop within the WebBrowser Pin
Tekapo29-Jul-04 4:35
memberTekapo29-Jul-04 4:35 
GeneralAccessing body attributes in mshtml Pin
e11even27-Jul-04 15:20
membere11even27-Jul-04 15:20 
GeneralRe: Accessing body attributes in mshtml Pin
Sam Hobbs6-Apr-09 13:30
memberSam Hobbs6-Apr-09 13:30 
GeneralProblems with .aspx pages and 3rd party control Pin
JimmyG1328-Jun-04 5:30
memberJimmyG1328-Jun-04 5:30 
Generalgood work nikhil Pin
myself_achint@yahoo.co.in13-Jun-04 7:29
membermyself_achint@yahoo.co.in13-Jun-04 7:29 
GeneralRe: good work nikhil Pin
Anonymous23-Nov-04 3:12
sussAnonymous23-Nov-04 3:12 
GeneralRe: good work nikhil Pin
Anonymous30-Nov-04 6:31
sussAnonymous30-Nov-04 6:31 
GeneralCapturing the click event of the image button element Pin
udvranto27-May-04 13:44
memberudvranto27-May-04 13:44 
QuestionRe: Capturing the click event of the image button element Pin
nmentink10-Oct-07 23:07
membernmentink10-Oct-07 23:07 
GeneralWebRequest + MSHTML Pin
Vitaliy S. Drozd6-Mar-04 22:01
sussVitaliy S. Drozd6-Mar-04 22:01 
GeneralMor MSHTML editing stuff... Pin
JoergKrause19-Jan-04 23:34
memberJoergKrause19-Jan-04 23:34 
GeneralNeed Information Pin
AlexBoy17-Sep-03 21:30
memberAlexBoy17-Sep-03 21:30 
GeneralProblem in getting the html content Pin
shivsun11-Jun-03 0:47
membershivsun11-Jun-03 0:47 
GeneralNeed help regarding parsing form input elements Pin
shivsun2-Jun-03 2:09
membershivsun2-Jun-03 2:09 
Questionhow to manipulate the darg and drop of the webbrowser editor!! Pin
zhuiqiu11113-Mar-03 21:46
memberzhuiqiu11113-Mar-03 21:46 
AnswerRe: how to manipulate the darg and drop of the webbrowser editor!! Pin
ly_he30-Jan-07 21:23
memberly_he30-Jan-07 21:23 
GeneralDocument events Pin
Darryn6-Mar-03 17:57
memberDarryn6-Mar-03 17:57 
GeneralUnable to trap the BeforeNavigate2 event Pin
Richard Hauer2-Mar-03 19:35
memberRichard Hauer2-Mar-03 19:35 
GeneralRe: Unable to trap the BeforeNavigate2 event Pin
Nikhil Dabas3-Mar-03 8:08
memberNikhil Dabas3-Mar-03 8:08 
GeneralForm Submit button does not work Pin
timtran27-Feb-03 8:01
membertimtran27-Feb-03 8:01 
GeneralRe: Form Submit button does not work Pin
ykikuchi17-Jun-04 19:01
memberykikuchi17-Jun-04 19:01 
GeneralRe: Form Submit button does not work Pin
uzunfatih9-May-06 22:53
memberuzunfatih9-May-06 22:53 
QuestionCannot write text in input text fields!? Pin
ActsOn12-Feb-03 0:04
sussActsOn12-Feb-03 0:04 
AnswerRe: Cannot write text in input text fields!? Pin
ActsOn12-Feb-03 5:03
memberActsOn12-Feb-03 5:03 
GeneralRe: Cannot write text in input text fields!? Pin
AK30-Jun-03 20:12
memberAK30-Jun-03 20:12 
GeneralRe: Cannot write text in input text fields!? Pin
AK1-Jul-03 9:18
memberAK1-Jul-03 9:18 
GeneralSinking events from HTMLDocument Pin
Cheng Tan9-Jan-03 8:38
memberCheng Tan9-Jan-03 8:38 
GeneralUsing HTML Files in Resource in C# Pin
KS Yuen25-Nov-02 8:01
memberKS Yuen25-Nov-02 8:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150731.1 | Last Updated 26 Jun 2002
Article Copyright 2002 by Nikhil Dabas
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid