The HTMLElementEvents2 interface is an event sink interface that enables an application to receive events for HTML elements. Your custom application can receive these events, which are fired in response to user actions on HTML elements, when hosting the WebBrowser Control or automating Microsoft? Internet Explorer.
The HTMLElementEvents2 interface is introduced and the steps required to receive notification of HTML element events from the browser are described, using Microsoft? Visual Studio? 5 or later.
It is assumed that a Microsoft Foundation Classes (MFC) application is hosting the WebBrowser Control, or launching Internet Explorer.
This article is divided into the following sections.
The IWebBrowser2::Navigate2 method of the IWebBrowser2 interface allows you to navigate the browser to a URL. Once an HTML page is loaded, you can access the HTML elements through the Dynamic HTML (DHTML) Object Model.
The DHTML Object Model is used to access and manipulate the contents of an HTML page and is not available until the page is loaded. Your application determines that the page is loaded by handling the DWebBrowserEvents2::DocumentComplete event of the WebBrowser Control. This event may be fired once for each frame in the page, and once when the top frame of the document is loaded. You can determine if the DWebBrowserEvents2::DocumentComplete event is for the top frame by comparing the IDispatch interface pointer passed by this event with that of the WebBrowser Control.
This sample handler code for the DWebBrowserEvents2::DocumentComplete event demonstrates how to determine if this event is for the top frame, which indicates that the HTML page has loaded. This sample also demonstrates how to create a stream from a block of memory―in this case a string that contains the HTML content to be displayed. The variable m_pBrowser contains the IWebBrowser2 interface pointer obtained from the WebBrowser Control.
Show Example
void CMyClass::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL) { HRESULT hr; IUnknown* pUnkBrowser = NULL; IUnknown* pUnkDisp = NULL; IDispatch* pDocDisp = NULL; IHTMLDocument2* pDoc = NULL; // Is this the DocumentComplete event for the top frame window? // Check COM identity: compare IUnknown interface pointers. hr = m_pBrowser->QueryInterface(IID_IUnknown, (void**)&pUnkBrowser); if (SUCCEEDED(hr)) { hr = pDisp->QueryInterface(IID_IUnknown, (void**)&pUnkDisp); if (SUCCEEDED(hr)) { if (pUnkBrowser == pUnkDisp) { // This is the DocumentComplete event for the top frame. // This page is loaded, so we can access the DHTML Object Model. hr = m_pBrowser->get_Document(&pDocDisp); if (SUCCEEDED(hr)) { // Obtained the document object. pDocDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc); if (SUCCEEDED(hr)) { // Obtained the IHTMLDocument2 interface for the document object ProcessDocument(pDoc); } pDocDisp->Release(); } } pUnkDisp->Release(); } pUnkBrowser->Release(); } }The IWebBrowser2::get_Document property on the WebBrowser Control retrieves the document object that represents the DHTML Object Model for the top frame.
Accessing an Element on the PageUsing the IHTMLDocument2 interface pointer, you can request a collection of all elements in the HTML document through the IHTMLDocument2::all property.
void CMyClass::ProcessDocument(IHTMLDocument2* pDoc) { IHTMLElementCollection* pElemColl = NULL; hr = pDoc->get_all(&pElemColl); if (SUCCEEDED(hr)) { // Obtained element collection. ProcessElementCollection(pElemColl); pElemColl->Release(); } }The IHTMLDocument2::all property returns a collection of all the HTML elements on the page through an IHTMLElementCollection interface pointer. You can use the IHTMLElementCollection interface to call the IHTMLElementCollection::item method and pass the name or id of an element as a parameter, as shown in the following code.
Note The IHTMLElementCollection::item method will return a collection if there is more than one element with the specified name or id. To prevent a collection from being returned, provide an index as the second parameter of IHTMLElementCollection::item to specify which element should be returned.
Show Example
void CMyClass::ProcessElementCollection(IHTMLElementCollection* pElemColl) { IDispatch* pElemDisp = NULL; IHTMLElement* pElem = NULL; _variant_t varID("myID", VT_BSTR); _variant_t varIdx(0, VT_I4); hr = pElemColl->item(varID, varIdx, &pElemDisp); if (SUCCEEDED(hr)) { hr = pElemDisp->QueryInterface(IID_IHTMLElement, (void**)&pElem); if (SUCCEEDED(hr)) { // Obtained element with ID of "myID". ConnectEvents(pElem); pElem->Release(); } pElemDisp->Release(); } }If you are working with HTML tags of a specific type, such as a tags, the IHTMLElementCollection::tags method returns a collection of all the elements that have the requested HTML tag name, also through an IHTMLElementCollection interface pointer.
Receiving Element EventsEach element in the DHTML Object Model supports an outgoing HTMLElementEvents2 interface. This interface defines the events that an HTML element can fire. You implement this interface to provide an event sink, which is a Component Object Model (COM) object that implements an outgoing interface and is used as the mechanism for firing events.
Note Interfaces implemented by a server usually have their methods called by the client, but to fire an event, the server calls the respective method on the client event sink. These interface are called outgoing interfaces. A COM object that implements an outgoing interface is also known as a connectable object.
The following steps are required to receive events from an outgoing interface:
Implement the event sink.
The event sink implements the appropriate outgoing interface and methods. Internet Explorer event interfaces are dispinterfaces, so calls to event methods are made through IDispatch::Invoke . This means that you only need to implement the IDispatch interface to handle events.
Determine if the server is a connectable object.
Call QueryInterface to retrieve a pointer to the IConnectionPointContainer interface.
Find the appropriate connection point.
Call the IConnectionPointContainer::FindConnectionPoint method to find the connection point you need. For Internet Explorer WebBrowser Control events, such as DWebBrowserEvents2::DocumentComplete, this is DWebBrowserEvents2. For element events, this is HTMLElementEvents2. You can also call the IConnectionPointContainer::EnumConnectionPoints to enumerate through all the connection points a server supports.
Advise the connection point that you want to receive events.
Using the IConnectionPoint interface pointer returned in the previous step, call IConnectionPoint::Advise , passing the IUnknown interface pointer of your event sink.
Note The connectable object will use the IUnknown interface pointer to query the client for the event sink interface. If the event sink does not support the outgoing interface, Internet Explorer will query the client for the IDispatch interface.
The following sample code demonstrates how to begin receiving HTML element events for an element on an HTML page.
Show Example
void CMyClass::ConnectEvents(IHTMLElement* pElem) { HRESULT hr; IConnectionPointContainer* pCPC = NULL; IConnectionPoint* pCP = NULL; DWORD dwCookie; // Check that this is a connectable object. hr = pElem->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC); if (SUCCEEDED(hr)) { // Find the connection point. hr = pCPC->FindConnectionPoint(DIID_HTMLElementEvents2, &pCP); if (SUCCEEDED(hr)) { // Advise the connection point. // pUnk is the IUnknown interface pointer for your event sink hr = pCP->Advise(pUnk, &dwCookie); if (SUCCEEDED(hr)) { // Successfully advised } pCP->Release(); } pCPC->Release(); } }The following sample code demonstrates how you would detect the firing of an HTMLElementEvents2::onclick event in your implementation of IDispatch::Invoke.
Show Example
STDMETHODIMP CEventSink::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { switch (dispidMember) { case DISPID_HTMLELEMENTEVENTS2_ONCLICK: OnClick(); break; default: break; } return S_OK; } Handling Events using MFCThe following articles provide information about the WebBrowser Control and MSHTML.
The following articles provide information about Visual Studio.
The following articles provide information about COM.