Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

template <class T>

class CHtmlEventObject : public IDispatch {

 typedef void (T::*EVENTFUNCTIONCALLBACK)(DISPID id, VARIANT* pVarResult);

public:

 CHtmlEventObject { m_cRef = 0; }

 ~CHtmlEventObject {}

 HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) {

*ppvObject = NULL;

if (IsEqualGUID(riid, IID_IUnknown)) *ppvObject = reinterpret_cast<void**>(this);

if (IsEqualGUID(riid, IID_IDispatch)) *ppvObject = reinterpret_cast<void**>(this);

if (*ppvObject) {

((IUnknown*)*ppvObject)->AddRef;

return S_OK;

} else return E_NOINTERFACE;

 }

 DWORD __stdcall AddRef {

return InterlockedIncrement(&m_cRef);

 }

 DWORD __stdcall Release {

if (InterlockedDecrement(&m_cRef) == 0) {

delete this;

return 0;

}

return m_cRef;

 }

 STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo) {

return E_NOTIMPL;

 }

 STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) {

return E_NOTIMPL;

 }

 STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames,

LCID lcid, DISPID FAR* rgDispId) {

return S_OK;

 }

 STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid,

WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,

EXCEPINFO * pExcepInfo, UINT * puArgErr) {

if (DISPID_VALUE == dispIdMember) (m_pT->*m_pFunc)(m_id, pVarResult);

else TRACE(_T("Invoke dispid = %d\n"), dispIdMember);

return S_OK;

 }

public:

 static LPDISPATCH CreateHandler(T* pT,

EVENTFUNCTIONCALLBACK pFunc, DISPID id) {

CHtmlEventObject<T>* pFO = new CHtmlEventObject<T>;

pFO->m_pT = pT;

pFO->m_pFunc = pFunc;

pFO->m_id = id;

return reinterpret_cast<LPDISPATCH>(pFO);

 }

protected:

 T* m_pT;

 EVENTFUNCTIONCALLBACK m_pFunc;

 DISPID m_id;

 long m_cRef;

};

Как применять этот класс? Проще простого.

Шаг 1. Создаем свою функцию обработчик по прототипу onevent(dispid id, VARIANT* pVarResult). В принципе ее можно разместить где угодно. Я предпочитаю создавать ее в классе представления, наследнике CHtmlView. При этом все обработчики сосредоточены в одном месте и не нужно беспокоится о взаимодействии с классом документа.

Шаг 2. Регистрируем ее в качестве обработчика интересующего нас события. Для этого через вызов CHtmlEventObject::CreateObject создаем экземпляр нашего COM-объекта. Передаем в него адрес функции обработчика и собственный идентификатор события. После этого передаем ссылку на него интересующему нас элементу.

// Создаем объект-обработчик

LPDISPATCH dispFO = CHtmlEventObject<CEventView>::CreateHandler(this, OnKeyDown, 1);

VARIANT vIn;

V_VT(&vIn) = VT_DISPATCH;

V_DISPATCH(&vIn) = dispFO;

// устанавливаем обработчик document.onkeydown

hr = pHtmlDoc->put_onkeydown(vIn);

Здесь есть одна тонкость. Зарегистрировать обработчик можно только тогда, когда документ уже загружен, иначе GetHtmlDocument вернет NULL. Для этого можно отслеживать событие OnDocumentComplete. Ну вот собственно и все.

Получаем информацию о событии
  • Читать дальше
  • 1
  • ...
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: