MSHTML Hosting – The Basics

Hosting IE in your application is a relatively straight forward process, provided your development environment supports the use of ActiveX controls. Each language/framework has its own way of doing it: VB works directly with the WebBrowser control, MFC has its CHtmlView wrapper classes, Delphi has the TWebBrowser wrapper and C++Builder uses TCppWebBrowser. Create one of these somewhere in your application and your on your way to displaying HTML pages.

Before I go any further, I want to point you to the MSDN documentation of reusing the WebBrowser control. It will be an invaluable reference to you.

The WebBrowser control is really made up of a command interface (IWebBrowser2) and event interfaces (DWebBrowserEvents and DWebBrowserEvents2). Unless you are writing code against the raw control (please don’t), your wrapper component will expose both of these sides to you automatically. The event names may be slightly different between components. Here are the most useful methods and events:

  • Document – This property is your means to gain access to the IHTMLDocument2 MSHTML interface. More on this in later posts, I just wanted to point it out now.
  • Navigate / Navigate2 – Provides a simple way to tell the WebBrowser to display a page from a given file or URL. Remember to specify the full URL (including http://). Navigate is the simpler method. Both support functionality such as passing in flags to keep the page from displaying in IE’s cache list.
  • GoHome / GoBack / GoForward / Refresh – Allow you to mimic the IE functionality with the respective names.
  • ExecWB – Provides a way to get the WebBrowser to execute commands (listed here), such as Print, Print Preview, Save As, Copy and Find.
  • OnBeforeNavigate2 – Event that is called before the WebBrowser actually navigates to a given page. This event allows you to cancel or redirect the navigation. Many embedded browser applications use this event to implement “custom protocols” where clicking on a link will display your dialog, for example.
  • OnDocumentComplete – Event that is called when a page is fully loaded into the browser. Use this event as a trigger for hooking up other functionality that can only be done after a page is completely in the browser.
  • OnNavigateComplete2 – Event that is fired as individual pieces of the page are loaded. Many people assume this event will only be called once per page load. Not true, it is called once for each frame and then for the page. It is usually safer to use OnDocumentComplete, unless you need to be notified for each frame.

Using these methods and events, it is very easy to create a nicely featured web browser. Next time we can look at ways to make WebBrowser seem less like a web browser and more like a custom HTML display control you can use inside your application.

Working With MSHTML Hosting

On the surface it seems like a great deal. You can actually embed MSHTML, the IE HTML rendering engine, in your own application. There is a lot of cool, simple features you get out-of-the-box. As soon as you get more advanced in your features, you find things are not so simple.

First, lets clear up some terminology:

  • WebBrowser – is an ActiveX control that you can embed in your applications to create a mini webbrowser. It will display HTML pages just as well as IE itself.
  • MSHTML – is a set of COM interfaces that you can use to programmatically access the elements of an HTML page. The interfaces also allow you to take part in Dynamic HTML events as well as behind the scenes operations like editing, custom rendering and behaviors, and selection.

WebBrowser depends on MSHTML. In fact there is not much beyond navigating to an HTML page that you can do with WebBrowser alone.

Myself and my team have become quite familiar with the ins and outs of MSHTML hosting. Never have I seen a more clear case of the 80/20 rule. MSHTML will get you 80% of your features very quickly and with relative ease. That last 20% will break most of you.

By no means do I consider myself an expert on MSHTML hosting, but I have implemented some tough features. One of the hardest things about moving past the beginner level stuff is the lack of real examples. I thought I would collect some links to stuff I found useful and post some code examples as well.

More to come

Mini-Milestones Can’t Slip

I am a big proponent of the staged delivery concept of software development. McConnell’s treatment really brought it home for me when I first read Software Survival Guide. The recent Agile methods also preach the same ideas. It’s just good sense: Always have a buildable, releasable product.

The reason for this post is not to act as a cheerleader for staged delivery. It’s to vent-off some steam. At work, we have created a system of mini-milestones we are using to implement staged delivery. The other day we decide to slip a mini-milestone! Feature-creep /scope-creep caused us to miss a milestone!

I lost it. These milestones aren’t for creating releases (we are far from that). The milestones act as checkpoints during the development process. The fact that we slipped a mini-milestone tells me that our process needs to be examined. The fact that we slipped is a red flag to me. If we can’t contain scope-creep now, at this early point in the process, there is no way we can contain it later.