Add Internet Browsing to Your MFC Applications with the Microsoft Internet Explorer Control

Mark Davis

Want to provide seamless Internet browsing from your MFC applications? You can, using the Microsoft Internet Explorer Web browser control. This article shows you how to add Internet browsing capability to your applications with the Web browser control in an MFC application using Microsoft Visual C++ 4.

MOST users navigate the Internet using their favorite browser to specify the address (URL) of each Web site they wish to visit. As you can imagine, the browser does a lot of work connecting to the Web site, downloading the specified HTML page, and then interpreting the contents. Because of the rich content available on a Web page, a browser also needs to be able to interpret an evolving set of HTML commands. HTML defines the content, layout, and style of a Web page. HTML tags specify elements such as:

URL links

frames

entry forms

images

style sheets

scripting languages such as VBScript and JScript

ActiveX controls

Java applets

It’s no wonder that writing and maintaining your own Internet browser isn’t for the faint-hearted.

With so many people accessing the Internet and so much content available, you may wonder how you can incorporate some of this technology into your own applications, without the effort of writing and maintaining your own browser. This article discusses how you can use the Microsoft Internet Explorer browser in your own application.

Why add Internet browsing capabilities?

There are many compelling reasons why you might want users to browse the Internet from within your application. These are just a few of the reasons:

Support and advertising: Providing a quick method for your users to reach your Web site, find out about other products, and download updates.

Personal information management: Navigating to URLs stored in a Ôfavorite Web sites’ database.

Web tools: Providing Web site map and printing features.

General browsing: Rolling your own customized browser to view Web pages and the file system.

Explore your options with Microsoft Internet Explorer

Before I talk about the Microsoft Internet Explorer Web browser control, you may want to consider alternative ways you can use the IE browser. The most basic of these is to launch the browser as a separate application. The sample application demonstrates different ways to do this, including calling the following:

The Win32 CreateProcess function, passing the Internet Explorer executable path and file name in lpApplicationName and the URL in lpCommandLine.

The Win32 ShellExecute function, passing the URL in lpFile.

The ActiveX SDK HlinkNavigateString function, or related functions, passing the URL.

These and other methods have a major drawback in that the developer has little or no control over how the browser is displayed. Once the browser is launched, it’s up to the user to close it down or switch back to your application.

Once the Microsoft Internet Explorer has been launched, two other techniques, the IWebBrowserApp OLE Automation interface and DDE, can be used to control the browser. For more information on these interfaces, please refer to the information sources at the end of this article.

The Microsoft Internet Explorer Web browser control

The Web browser control is installed with Microsoft Internet Explorer 3.0. It provides the view you see in the main window of the Microsoft Internet Explorer and it provides the functionality for displaying Web pages containing HTML, scripting, and ActiveX control and Java applet content. The control also hosts OLE document objects, supports OLE hyperlinks, and allows users to view Windows objects such as folders and files. Because it’s an ActiveX control, it can be used in your MFC and Visual Basic applications, or any other OLE control container. Like other ActiveX controls, the browser control exposes a number of methods, properties, and events through the IWebBrowser OLE Automation interface, as described in Tables 1, 2, and 3.

Table 1. Web browser control methods.

Method Description
GoBack Navigates to the previous item in the history list.
GoForward Navigates to the next item in the history list.
GoHome Navigates to the current configured home or start page.
GoSearch Navigates to the current configured search page.
Navigate Navigates to a resource identified by a URL or file path.
Refresh Reloads the current page.
Refresh2 Reloads the current page and optionally specifies the refresh level.
Stop Stops any pending navigation or download.

Table 2. Web browser control properties.

Property Description Method
Application Automation object representing the containing application. Get
Busy Indicates whether a download or navigation is still in progress. Get
Container Container of the WebBrowser control, if any. Get
Document Automation object of the active document, if any. Get
Height Vertical dimension, in pixels, of the frame window that contains the WebBrowser control. Get/Put
Left Distance between the internal left edge of the WebBrowser control and the left edge of its container. Get/Put
LocationName Name of the resource that the WebBrowser control is currently displaying. Get
LocationURL URL of the resource that the WebBrowser control is currently displaying. Get
Parent Form on which the WebBrowser control is located. Get
Top Distance between the internal top edge of the WebBrowser control and the top edge of its container. Get/Put
TopLevelContainer Indicates whether the current object is a top level container. Get
Type Type of the current contained document object. Get
Width Horizontal dimension, in pixels, of the frame window that contains the WebBrowser control. Get/Put

Table 3. Web browser control events.

Event Description
BeforeNavigate Occurs when the WebBrowser control is about to navigate to a new URL.
CommandStateChange Occurs when the enabled state of a command changes.
DownloadBegin Occurs when a navigation operation is beginning, shortly after the BeforeNavigate event.
DownloadComplete Occurs when a navigation operation is finished.
FrameBeforeNavigate Occurs when the WebBrowser control is about to navigate to a new URL in an HTML frame.
FrameNavigateComplete Occurs after the browser has successfully navigated to a new URL in an HTML frame.
FrameNewWindow Occurs when a new window is to be created for displaying a resource in an HTML frame.
NavigateComplete Occurs after the browser has successfully navigated to a new URL.
NewWindow Occurs when a new window is to be created for displaying a resource.
ProgressChange Occurs when the progress of a download is updated.
PropertyChange Occurs when the PutProperty method changes the value of a property.
Quit Occurs when the Internet Explorer application is ready to quit.
StatusTextChange Occurs when the status bar text has changed.
TitleChange Occurs when the title of a document in the WebBrowser control becomes available or changes.

Inserting and creating the Web browser control

Using the MFC AppWizard in Visual C++ 4, create a new MFC application selecting support for OLE Controls. The sample application, which you can download from the Visual C++ Developer home page at www.pinpub.com/vcd, is an SDI application with the view based on CView. You could also base your view on CFormView or create a dialog-based application, both of which use dialog templates for arranging Windows controls.

In the Component Gallery, you’ll see the Microsoft Web Browser Control listed in the OLE Controls section. When you insert this control, the dialog box in Figure 1 is displayed, showing the default class and filenames for the control class to be generated. So what is the CWebBrowser class? Well, support for hosting an OLE control is implemented in the MFC CWnd class, from which your newly generated class is derived. The CWebBrowser class is generated by Visual C++ from the control’s type library and provides helper functions for accessing the control methods and properties though the control’s OLE Automation interface, IWebBrowser.

Figure 1. Confirm Web browser control class dialog.

Once the Web browser control has been inserted into the project, it becomes available as an additional control in the resource editor. The control can simply be dropped onto a dialog box template as you would any other Windows control. Just assign a resource ID and a control variable to access it. Because the sample application uses a view based on CView, the Web browser control will be created dynamically, a technique that has the benefit of allowing the user to resize the view. In this example, the ID_BROWSE symbol is assigned (using View É Resource Symbols) to the control. Here’s how you would dynamically create the Web browser control:

int CMyView::OnCreate(LPCREATESTRUCT 
                      lpCreateStruct)
{
  if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;
	
    // Create Web browser control
       if ( ! m_Browse.Create( NULL, WS_CHILD|
                            WS_VISIBLE, CRect(),
                            this, ID_BROWSE ) )
	return -1;

	return 0;
}

void CMyView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// Resize Web browser control
	m_Browse.MoveWindow( 0, 0, cx, cy );
	m_Browse.UpdateWindow();
}

Accessing the Web browser control

Once the control has been created, a mechanism is needed to obtain the URL from the user and then invoke the Navigate method. In the sample application I’ve demonstrated one way to do this: Create a drop-down combo on the toolbar and handle “Enter” key press events. Having obtained the URL, a function in the view class can invoke the control’s Navigate method:

void CMyView::DoNavigate(LPCSTR pszUrl)
{
COleVariant varEmpty; // Default is VT_EMPTY
	m_Browse.Navigate( pszUrl, &varEmpty, 
                         &varEmpty, 
                         &varEmpty, 
                         &varEmpty );
}

It’s easy to wire up additional toolbar buttons for the other methods, such as Refresh and Stop. You can find an example in the sample application. With a few lines of code, the application looks and feels like an Internet browser.

Handling Web browser control events

Just as exposed methods are invoked, events fired by the control can be handled easily using the MFC event map framework. If the control is created by dropping it onto a dialog box resource, each event is handled by selecting the appropriate CDialog or CFormView derived class, Object ID, and Message displayed in ClassWizard Message Maps section, as shown in Figure 2.

Figure 2. Web browser control events as shown in ClassWizard.

If control was created dynamically in the sample application, you may be wondering why the control’s resource ID (such as ID_BROWSE) isn’t shown. The reason is that ClassWizard doesn’t know which class is bound to the new resource¾the symbol is used solely for referencing the control, so the following trick is required to take advantage of the MFC event map created by ClassWizard.

Here’s how to add event support for a dynamically created OLE control: Edit any dialog box resource (such as IDD_ABOUTBOX) and drop the Web browser control onto the dialog template. While in the resource editor, run ClassWizard, then select your view class in the Class Name drop-down and select the IDC_EXPLORER1 Object ID. For each event you wish to handle, select the event name from the Messages list and use Add Function to add the member function. When all event handlers have been added, modify the event sink map generated by ClassWizard so that the correct resource ID is used and then delete the unwanted control from the dialog resource.

In the sample application, I’ve handled the TitleChange and StatusTextChange events and have updated the document title and status bar accordingly. The BeforeNavigate event is handled to detect when a new URL is selected and the PropertyChange event is handled to detect when a page has been parsed. You could, for example, handle the DownloadBegin, DownloadEnd, and ProgressChange to display a Ôbusy’ animation or progress control.

Accessing the Internet Explorer Object Model

The Web browser control exposes the Internet Explorer Object Model, a collection of OLE Automation objects hosted by the control when a Web page is displayed. This model is primarily intended for use by scripting languages such as VBScript or Jscript and to allow access to objects such as frames and links. The structure of the object model is shown in Figure 3.

Figure 3. Microsoft Internet Explorer Object Model. The asterisk (*) indicates a collection.

The OLE Automation objects that comprise the Internet Explorer Object Model are implemented in MSHTML.DLL, located in your Windows system folder. ClassWizard creates MFC OLE Automation client classes from the type library in this DLL. These classes are derived from the COleDispatchDriver class, which provides easy access to the methods and properties of an OLE Automation object. When ClassWizard is used to add classes from the MSHTML.DLL type library, the dialog box shown in Figure 4 is displayed.

Figure 4. Confirm Internet Explorer Object classes dialog box.

The sample application demonstrates how to access some of the Internet Explorer objects to show the URL links on the current Web page. It does this by getting the value of the Web browser control’s Document property. This property is the dispatch interface (IDispatch) for the active document and is attached to an IHTMLDocument C++ object by calling its AttachDispatch method. The IHTMLDocument Script property provides the dispatch interface for the Window object and is attached to an IOmWindow C++ object. From this point, any of the other objects shown in Figure 3 can be accessed.

Handling scripting object events

The Web browser control doesn’t fire an event to notify the application when the HTML page has been parsed and the Internet Explorer objects are ready to be accessed. Fortunately, the IOmWindow object fires an OnParseComplete event. But hold on here¾these are OLE Automation objects, not controls, so how is this event being fired? Well, the Window object implements an outgoing interface, also known as a connection point, called IOmWindowEvents. These events are handled on the client side by implementing an event sink.

An event sink is implemented by creating a class derived from CCmdTarget with Automation support selected. ClassWizard generates a new GUID when this class is created, so the GUID needs to be modified to match that of the IOmWindowEvents interface. The Ole2View utility provided with Microsoft Visual C++ can be used to view the type library (in MSHTML.DLL) to obtain the IOmWindowEvents interface GUID and methods. The methods, onParseComplete, onLoad, and onUnload are added to the event sink class using the ClassWizard OLE Automation facility.

The sample application demonstrates how to inform the IOmWindowEvents connection point that our event sink wants to be notified of these events. This notification is done in the ConnectWindowEvents function, implemented in the view class, and does the work of accessing the Window object, finding the IOmWindowEvents connection point, and calling its Advise method.

Conclusion

I hope I’ve enabled you to get started with this exciting control. Now it’s up to you to explore this technology and determine where to apply it to future applications.

For More Information

See the Microsoft Visual C++ help for more information on the MFC implementation of OLE Controls, OLE Automation, and connection points.

See the ActiveX SDK help for more information on the Web browser control, Internet Explorer Object Model for Scripting, and URL monikers.

For a more accurate mechanism to detect when a Web page has been loaded by Internet Explorer, you may want to look at the OBJVW (BASECTRL) sample provided with the ActiveX 3.01 SDK. This sample also provides a generic event sink class.

The following are useful Web links:

ActiveX SDK
http://www.microsoft.com/intdev/sdk
Internet Explorer DDE interface
http://www.microsoft.com/ie/support/docs/tech30/dde.htm
Internet Explorer Web Browser Control
http:// www.microsoft.com /intdev/sdk/docs/iexplore/webrowse.htm
Internet Explorer Object Model
http:// www.microsoft.com /intdev/sdk/docs/scriptom/omscript.htm
URL Monikers and OLE Hyperlinks
http:// www.microsoft.com /intdev/prog-gen/moniker.htm

DAVIS.ZIP at www.pinpub.com/vcd

Mark Davis specializes in Microsoft Visual C++, Microsoft Foundation Classes, ActiveX, OLE, and COM. Mark lives with his supportive wife, Janine, and children, Kurt and Adam.

http://www.geocities.com/Siliconvalley/heights/1720

To find out more about Visual C++ Developer and Pinnacle Publishing, visit their website at: http://www.pinppub.com/vcd/

Note: This is not a Microsoft Corporation website.
Microsoft is not responsible for its content.

This article is reproduced from the February 1997 issue of Visual C++ Developer. Copyright 1997, by Pinnacle Publishing, Inc., unless otherwise noted. All rights are reserved. Visual C++ Developer is an independently produced publication of Pinnacle Publishing, Inc. No part of this article may be used or reproduced in any fashion (except in brief quotations used in critical articles and reviews) without prior consent of Pinnacle Publishing, Inc. To contact Pinnacle Publishing, Inc., please call (800) 788-1900 or (206) 251-1900.