I'm creating a Browser Helper Object using VS2008, C++. My class has been derived from IDispEventImpl among many others
class ATL_NO_VTABLE CHelloWorldBHO :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
public IObjectWithSiteImpl<CHelloWorldBHO>,
public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
{
.
.
.
BEGIN_SINK_MAP(CHelloWorldBHO)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)//Handle BeforeNavigate2
END_SINK_MAP()
.
.
.
}
As apparent from the code above, my DWebBrowserEvents2 are handled using the ATL's macros. Now I want to handle HTMLElementEvents2 (to detect clicks, scrollbars, etc.) For that, I QueryInterface() the IHTMLDocument2 object for IHTMLElement, QueryInterface() that for IConnectionPointContainer and call IConnectionPointContainer::FindConnectionPoint(DIID_HTMLElementEvents2). (See msdn's article on handling HTMLElementEvents2). The problem is, when I overwrite IDispatch::Invoke in my class, the DWebBrowserEvents2 handles (created using ATL macros) fail. Is there a way to handle HTMLElementEvents2 without overwriting Invoke, or implement invoke in such a way that it only handles HTMLElementEvents2?
Thanks, Any help will be appreciated.
There is no real need to override Invoke or get IConnectionPointContainer. Since this is an ATL project, Implementing another IDispEventImpl:
does the trick. Then, sink the entry as:
In OnDocumentComplete, call IWebBrowser2::get_Document, IHTMLDocument2::get_body, and then call DispEventAdvise to start receiving events.
Note that I've used DIID_HTMLTextContainerEvents2 instead of DIID_HTMLElementEvents. That's because the body object does not support HTMLElementEvents2, and for my purpose (to handle scrolling) this works just fine!