Алекс Jenter - Программирование на Visual C++. Архив рассылки

Здесь есть возможность читать онлайн «Алекс Jenter - Программирование на Visual C++. Архив рассылки» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Программирование на Visual C++. Архив рассылки: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Программирование на Visual C++. Архив рассылки»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ
, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Программирование на Visual C++. Архив рассылки», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Замечу, что это не единственный способ заставить приложения реагировать на события. Например, можно заставить работать механизм window.external. Тогда соответствующий скрипт будет выглядеть например, так:

function mousedownhandler() {

// функция обработки window.external.onmousedown;

}

Думаю идея понятна. Однако этот способ удобен если мы сами формируем страницу. Сегодня мы пойдем первым путем.

Пишем шаблоный класс

Итак, настало время применить все вышеизложенное на практике. Конечно, можно руками написать COM-объекты для каждой функции, однако представьте, что число обработчиков переваливает за десяток, а каждый раз нужно реализовывать по сути одно и тоже. Думаю, понятно, к чему я клоню :) Самое время вспомнить о шаблонах C++. Итак, напишем простенький шаблонный класс. Чтобы не зависеть от конкретной библиотеки реализуем пару IUnknown, IDispatch вручную. Реализация IUnknown вполне стандартна, а из IDispatch необходимо реализовать только функцию Invoke.

template

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(this);

if (IsEqualGUID(riid, IID_IDispatch)) *ppvObject = reinterpret_cast(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* pFO = new CHtmlEventObject;

pFO->m_pT = pT;

pFO->m_pFunc = pFunc;

pFO->m_id = id;

return reinterpret_cast(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::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. Ну вот собственно и все.

Получаем информацию о событии

Рассмотрим еще раз прототип функции обработчика

OnEvent(DISPID id, VARIANT* pVarResult);

В качестве id передается значение которое мы указали при регистрации обработчика. Это может пригодиться если мы захотим реализовать обработку нескольких событий в одной функции. Для этого нужно зарегистрировать одну и ту же функцию с разными DISPID, тогда по приходу событий мы сможет их различать.

pVarResult нужно, если не требуется обработки по умолчанию. При этом достаточно в pVarResult вернуть VARIANT_FALSE.

Итак, когда вызывается наш обработчик никакой дополнительной информации о событии в функцию не передается. А как же тогда поподробнее узнать, что произошло? Для этого необходимо воспользоваться интерфейсом IHTMLEventObj, доступным через объект window текущего документа. Посредством этого интерфейса можно получить подробную информацию о произошедшем событии, например, элемент, послуживший источником событий, состояние клавиш, местоположение курсора мыши и состояние ее кнопок.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Программирование на Visual C++. Архив рассылки»

Представляем Вашему вниманию похожие книги на «Программирование на Visual C++. Архив рассылки» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Алексей Макеев - Смертельный архив
Алексей Макеев
libcat.ru: книга без обложки
Алексей Апухтин
Отзывы о книге «Программирование на Visual C++. Архив рассылки»

Обсуждение, отзывы о книге «Программирование на Visual C++. Архив рассылки» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x