When writing an ActiveX control for the Internet, it may often be necessaryto access the object model of the HTML page. The object model allows accessto various elements within the HTML page.
This article discusses accessing the object model from Visual C++ and fromVisual Basic, and covers both Internet Explorer (IE) 3.x and 4.0.
THE OBJECT MODEL
Documentation for the object model can be found in the ActiveX SoftwareDevelopment Kit (SDK) and the Internet Client SDK for Internet Explorer 3.xand 4.0, respectively. The object model is documented as follows:
window - location - frames - ... - document - links - forms - elements
The window object is at the top level of this hierarchy. The window has adocument property, which in turn has its own set of properties. Pleaseconsult the appropriate SDK for further details.
WHY SHOULD A CONTROL NEED TO ACCESS THE OBJECT MODEL?
A control can access (and in some cases modify) information about the pagethat it is embedded in. To do so, the control must access the object model.For example, a control can enumerate all of the elements on a page. In thecase of dynamic HTML, the control can access almost any HTML element in thepage.
ACCESSING THE OBJECT MODEL
The object model is implemented using automation and COM interfaces. Oncethe control is able to access the top level of the object model, then itcan drill down the object model using automation or COM interfaces. Thisarticle discusses both steps:
- Getting to the top level of the object model.
- Drilling down into the object model.
GETTING TO THE TOP LEVEL OF THE OBJECT MODEL (VISUAL C++)
Using IWebBrowserApp (for Internet Explorer 3.x and 4.x)
IWebBrowserApp is an interface that is exposed by the Web Browser control.It has a document property (or get_document method if using vtableinterface) that allows access to the automation object of the activedocument. If the document is an HTML document, then the automation objecthas a script property that gives the window object of the scripting objectmodel. So, for a control to reach the object model, the following must bedone:
- Obtain IWebBrowserApp from its containing HTML page.
- Get the document property of IWebBrowserApp.
- Get the script property of the document.
This will put you at the top level (window object) in the object model.Then use automation to drill down further.
Obtaining the IWebBrowserApp
Getting the IWebBrowserApp is a two-step process:
- Use the IOleClientSite pointer to get IServiceProvider. In an ATL control, this pointer can be obtained by accessing the m_spClientSite member of the control. In an MFC control, this pointer can be obtained by calling COleControl::GetClientSite(). The control has access to the IOleClientSite interface of its container. It can use that pointer to QI for IServiceProvider:
pClientSite->QueryInterface(IID_IServiceProvider, (void **)&pISP);
- Use the IServiceProvider to obtain IWebBrowserApp. Using the IServiceProvider, a QueryService can be done to get the IWebBrowserApp:
pISP->QueryService(SID_SWebBrowserApp, IID_IWebBrowserApp, (void **)&pIWebBrowserApp));
Also, if you are programming for Internet Explorer 4 or later, you canobtain a pointer to the IWebBrowser2 interface of the container with thiscode:
pISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&pIWebBrowser2));
QueryService is different from QueryInterface in that it does not have tofollow the identity rule in COM. So, if the object itself does notimplement IWebBrowserApp, it can delegate to the containing object andQueryService it for a IWebBrowserApp.
Get the Document Property of IWebBrowserApp
IWebBrowserApp is a dual interface. It has a document property and also aget_Document method. Either can be used to get the IDispatch of the activedocument. Once you have the IDispatch, then the script property can beobtained.
Get the Script Property of the Document
Using the IDispatch obtained above, get the script property usingautomation. This will give the top level in the scripting object model, orthe window object.
GETTING THE TOP LEVEL OF THE OBJECT MODEL (VISUAL C++)
(Internet Explorer 4.0 ONLY)
Internet Explorer 4.0 makes accessing the object model much easier. This isa one-step process:
- Get the IHTMLDocument2 from the IClientSite.
Obtaining IHTMLDocument2 from IOleClientSite
Every control has access to IClientSite of its container. QI-ing forIHTMLDocument2 from the client site should give the scripting object model.
IOleContainer* pContainer = NULL; IHTMLDocument2* pDoc = NULL; pClientSite->GetContainer( &pContainer ); if ( pContainer != NULL ) pContainer->QueryInterface( &IID_IHTMLDocument2, &pDoc );
Check the return value from the above call. If the control is not embeddedwithin an HTML page, or if the container is not Internet Explorer 4.0, thenthe above call will fail.
Getting IHTMLDocument2 gives the document object in the scripting objectmodel. Then either automation interfaces or vtable interfaces can be usedto drill down the object model.
GETTING THE TOP LEVEL OF OBJECT MODEL (VISUAL BASIC)
The parent property of the UserControl can be used to access the automationobject. From the Visual Basic documentation for the parent property,Internet Explorer returns an object whose Script property returns theIOmWindow object.
The example given in Visual Basic documentation is as follows:
Parent.Script.get_document.bgColor = "Blue"
The Parent property gets to the automation object. Then the script propertygives us the window object of the scripting object model. Then thedifferent properties and methods can be accessed just like any otherautomation object.
The above line of code should read as follows:
Parent.Script.document.bgColor = "Blue"
Even though using get_document is correct in Internet Explorer 3.x, it willnot work in Internet Explorer 4.0. The correct method is to use thedocument property. This will work both in Internet Explorer 3.x and 4.0.
DRILLING DOWN THE OBJECT MODEL
Drilling down the object model is as simple as calling the properties andmethods using automation. For Internet Explorer 3.x, use only automation.For Internet Explorer 4.0, vtable interfaces can be used. For moreinformation refer to the driller sample in the Internet Client SDK.