Re[3]: Как логировать события html элементов в Internet Expl
От: vitaliy666  
Дата: 02.03.08 10:07
Оценка:
Здравствуйте, vitaliy666, Вы писали:

V>Здравствуйте, mager, Вы писали:


M>>Здравствуйте, vitaliy666, Вы писали:


V>>>Необходимо перехватывать(в целях логирования) следующие события:

V>>>1.Ввели текст в текстовое поле(input type=text ,textarea,input type=pass).
V>>>2.Кликнули по html элементу.
V>>>3.Навели мышь на некоторый html элемент.

V>>>Как это можно осуществить,в наличии имеется ссылка на экземпляр IWebBrowser2?

V>>>У меня пока только 1 идея -добавлять нужный мне обработчик этих событий во все html элементы (это точно можно сделать средствами javascript,думаю,COM интерфейсы тоже должны содержать что нибудь подобное).
V>>>Есть ли способ лучше?


M>>HRESULT hRet = IDispEventSimpleImpl<_nDocID, CSampleClass, &DIID_HTMLDocumentEvents2>::

M>> DispEventAdvise(spDocument, &DIID_HTMLDocumentEvents2);

M>>где spDocument — IHTMLDocument2*

M>>также твой класс также должен наследовать интерфейс IDispEventSimpleImpl
M>>также необходимо в нидере класса описать такую карту сообщений документа

M>> BEGIN_SINK_MAP(CSampleClass)

M>> SINK_ENTRY_INFO(_nDocID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnClick, &DocumentEventInfo)
M>> SINK_ENTRY_INFO(_nDocID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEOUT, OnMouseOut, &DocumentEventInfo)
M>> SINK_ENTRY_INFO(_nDocID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONKEYPRESS, OnKeyPress, &DocumentEventInfo)
M>> END_SINK_MAP()

V>Я унаследовал класс от IDispEventSimpleImpl<0, CHelloWorldBHO, &DIID_HTMLDocumentEvents2>,

V>Объявил карту событий.Проект не компилируется,потому что не найдено объявление DocumentEventInfo.
V>Где и как нужно данную переменную объявлять?

V>class ATL_NO_VTABLE CHelloWorldBHO :

V> public CComObjectRootEx<CComSingleThreadModel>,
V> public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
V> public IObjectWithSiteImpl<CHelloWorldBHO>,
V> public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
V> public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>,
V> //public IDispEventImpl<0, CHelloWorldBHO, &DIID_HTMLDocumentEvents2, &LIBID_MSHTML, 1, 1>
V> public IDispEventSimpleImpl<0, CHelloWorldBHO, &DIID_HTMLDocumentEvents2>
V>{
V>BEGIN_SINK_MAP(CHelloWorldBHO)
V> //SINK_ENTRY_EX(0, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnMouseClick)
V> SINK_ENTRY_INFO(0, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnMouseClick, &DocumentEventInfo)
V> SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)

V>END_SINK_MAP()

V> VARIANT_BOOL STDMETHODCALLTYPE OnMouseClick(IHTMLEventObj* _pEvtObj);
V>}

Разобрался —
нужно объявить структуру в заголовочном файле:
static _ATL_FUNC_INFO OnDocumentInfo = {
CC_STDCALL, // Calling convention.
VT_I4, // Return type.
1, // Number of arguments.
{VT_DISPATCH} // Argument types.
};

Соответственно,карта событий:
EGIN_SINK_MAP(CHelloWorldBHO)
//SINK_ENTRY_EX(0, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnMouseClick)
SINK_ENTRY_INFO(0, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnMouseClick, &OnDocumentInfo)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)

END_SINK_MAP()

Объявление обработчика:
VARIANT_BOOL STDMETHODCALLTYPE OnMouseClick(IDispatch* _pEvtObj);

Объявление класса:
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>,
public IDispEventSimpleImpl<0, CHelloWorldBHO, &DIID_HTMLDocumentEvents2>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.