MSHTML Hosting – IDocHostUIHandler

We can’t discuss embedding WebBrowser in an application without also discussing IDocHostUIHandler. The IDocHostUIHandler (and IDocHostShowUI) interface is the standard method provided by Microsoft for customizing how WebBrowser works when hosted in an application. Some of the things you can use IDocHostUIHandler to do include:

  • Disable standard right-click, context menu (or provide your own version)
  • Turn off the 3D border and scrollbars
  • Give the WebBrowser scripting engine access to your special purpose COM methods
  • Handle accelerator keys and URL’s before MSHTML gets them

IDocHostUIHandler is an interface that you need to implement. How you implement depends on your development language and environment. For most languages, it means deriving a class from IDocHostUIHandler, adding code to the methods you want and returning safe, default values from those you do not want.

The next step is giving MSHTML your implementation of IDocHostUIHandler. Again, this depends on your development language and environment. The easy way is the “ICustomDoc” method. The best way is the “IOleClientSite” method. There is a nice C# article on CodeProject that discusses both methods (as well as some other good WebBrowser information).

ICustomDoc

This method requires only IDocHostUIHandler to be implemented which keeps things simpler. However, you have to give the interface to MSHTML after each page is loaded. The best way to do it is in the OnDocumentComplete or OnNavigationComplete events. This is the method I currently use in my applications. Code looks something like this:


IHTMLDocument2* pDoc = ...;
ICustomDoc* pCustom = 0;
hr = pDoc->QueryInterface(IID_ICustomDoc, (void**)&pCustom);
if (SUCCEEDED(hr)) {
  pCustom->SetUIHandler(pMyDocHostUIHandler);
  pCustom->Release();
}

IOleClientSite

This method requires that you implement IOleClientSite, as well as IDocHostUIHandler. The benefit is that you only need to give the interfaces to MSHTML once, before any HTML is loaded. I have not used this method in my applications, so I have no code to show you. I am planning on using it soon. I’ll update this post when I am finished.

I am switching from ICustomDoc to IOleClientSite mainly because of a transient problem. When the WebBrowser control loads my custom HTML, it waits until it is completely loaded before getting my IDocHostUIHandler, so there is a split second where the borders and scrollbars are not displaying correctly. With IOleClientSite, WebBrowser asks for my IDocHostUIHandler before it loads the HTML.