问题
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.
回答1:
There is no real need to override Invoke or get IConnectionPointContainer. Since this is an ATL project, Implementing another IDispEventImpl:
public IDispEventImpl<2, CHelloWorldBHO, &DIID_HTMLTextContainerEvents2, &LIBID_MSHTML, 4, 0>
does the trick. Then, sink the entry as:
SINK_ENTRY_EX(2, DIID_HTMLTextContainerEvents2, DISPID_ONSCROLL, OnScroll)
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!
来源:https://stackoverflow.com/questions/1106659/handle-htmlelementevents2-when-dwebbrowserevents2-has-been-handled-using-atls-m