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

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


person GotAmye    schedule 09.07.2009    source источник


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

person GotAmye    schedule 17.07.2009
comment
Привет, GotAmye, я также пытаюсь написать BHO для обработки данных. Но я столкнулся с проблемой, когда контент заполняется с помощью javascript. скажем, если есть что-то вроде этого <div id="idtest"><table></table></div>, где table генерируется JS, то как получить содержимое таблицы. Есть ли какое-либо событие для dhtml или каким-то другим способом? Пожалуйста, предложите ... Спасибо p.s. Я разместил вопрос здесь.. http://stackoverflow.com/questions/3298160/how-to-get-complete-html-body-using-browser-helper-object-bho-in-case-of-dhtml - person Favonius; 22.07.2010