Обрабатывать HTMLElementEvents2, когда DWebBrowserEvents2 был обработан с помощью макросов ATL

StackOverflow https://stackoverflow.com/questions/1106659

Вопрос

Я создаю вспомогательный объект браузера, используя 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 (для обнаружения кликов, полос прокрутки и т.д.) Для этого я запрашиваю Interface() объект IHTMLDocument2 для IHTMLElement, QueryInterface() - для IConnectionPointContainer и вызываю IConnectionPointContainer::FindConnectionPoint(DIID_HTMLElementEvents2).(См. статья msdn's об обработке HTMLElementEvents2).Проблема в том, что когда я перезаписываю IDispatch::Invoke в моем классе, дескрипторы DWebBrowserEvents2 (созданные с использованием макросов ATL) завершаются сбоем.Есть ли способ обработать HTMLElementEvents2 без перезаписи Invoke или реализовать invoke таким образом, чтобы он обрабатывал только HTMLElementEvents2?
Спасибо, любая помощь будет оценена по достоинству.

Это было полезно?

Решение

Нет реальной необходимости переопределять 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 , и для моей цели (для обработки прокрутки) это работает просто отлично!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top