使用ATL的宏处理DWebBrowserEvents2时处理HTMLElementEvents2

时间:2009-07-09 21:59:38

标签: c++ visual-studio-2008 com atl bho

我正在使用VS2008,C ++创建一个浏览器帮助程序对象。我的课程来自IDispEventImpl等众多

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()
.
.
.
}

从上面的代码中可以明显看出,我的DWebBrowserEvents2是使用ATL的宏来处理的。现在我想处理HTMLElementEvents2(以检测点击,滚动条等)。为此,我在QueryInterface()IHTMLElement的IHTMLDocument2对象,QueryInterface()用于IConnectionPointContainer并调用IConnectionPointContainer :: FindConnectionPoint(DIID_HTMLElementEvents2)。 (有关处理HTMLElementEvents2的信息,请参阅msdn's article)。问题是,当我在我的类中覆盖IDispatch :: Invoke时,DWebBrowserEvents2句柄(使用ATL宏创建)失败。有没有办法处理HTMLElementEvents2而不覆盖Invoke,或以只处理HTMLElementEvents2的方式实现调用?
谢谢,任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

没有必要覆盖Invoke或获取IConnectionPointContainer。由于这是一个ATL项目,实现另一个IDispEventImpl:

public IDispEventImpl<2, CHelloWorldBHO, &DIID_HTMLTextContainerEvents2, &LIBID_MSHTML, 4, 0>

诀窍。然后,将条目下沉为:

SINK_ENTRY_EX(2, DIID_HTMLTextContainerEvents2, DISPID_ONSCROLL, OnScroll)

在OnDocumentComplete中,调用IWebBrowser2 :: get_Document,IHTMLDocument2 :: get_body,然后调用DispEventAdvise开始接收事件。

请注意,我使用了DIID_HTMLTextContainerEvents2而不是DIID_HTMLElementEvents。那是因为body对象不支持HTMLElementEvents2,并且为了我的目的(处理滚动)这很好用!