scriptable объекты в плагине содержания Internet Explorer

Я загружаю и устанавливаю Cygwin и Xming.

5
задан Georg Fritzsche 2 November 2009 в 22:55
поделиться

1 ответ

Обновление (выдача событий из плагинов)

Хорошо, поэтому с дополнительными комментариями gf я вижу, что желаемый механизм - это противоположный механизм выдачи событий из компонентов, предоставленных извне из DOM.

Это похоже на то, как могут обрабатываться события MSHTML, но объекты плагина должны будут проверять объекты, предоставленные ему, используя другой механизм.

На объектах, которые предоставляют события (или поддерживают присоединение) объекты для событий), предоставьте методы attachEvent и detachEvent через IDispatch (и через двойной интерфейс, если необходимо). Если вы хотите, чтобы это выглядело безупречно с элементами HTML, вам следует объявить их так же, как они предоставлены в IHTMLElement. Идентификаторы DISPID не обязательно должны совпадать, но порядок аргументов и типов должен совпадать.

Метод attachEvent (IHTMLElement2) @ MSDN
Метод detachEvent (IHTMLElement2) @ MSDN

(из MSHTML.IDL в SDK платформы)

[id(DISPID_IHTMLELEMENT2_ATTACHEVENT)] HRESULT attachEvent(
  [in] BSTR event,
  [in] IDispatch* pDisp,
  [retval, out] VARIANT_BOOL* pfResult);
[id(DISPID_IHTMLELEMENT2_DETACHEVENT)] HRESULT detachEvent(
  [in] BSTR event,
  [in] IDispatch* pDisp);

Когда вы получаете вызов через attachEvent, вам нужно будет связать название события с полученным объектом. Точно так же вам нужно будет очистить связь объекта с именем события, когда вы получите вызов через detachEvent.

Когда вы хотите создать событие, проверьте все сохраненные вами объекты на предмет методов, которые должны быть вызваны в соответствии с вашим событие. Теоретически вам не обязательно использовать то же имя метода, что и имя вашего события, но на практике будет легче поддерживать и управлять, если вы это сделаете. Сначала изучите сам IDispatch, вызвав GetIDsOfNames (), чтобы найти точное совпадение с вашим событием. Если нет, изучите IDispatchEx и найдите метод expando через GetDispID (), который соответствует вашему событию.

Интерфейс IDispatch @ MSDN
IDispatch :: GetIDsOfNames @ MSDN (определение метода события получателя)
Интерфейс IDispatchEx @ MSDN
IDispatchEx :: GetDispID @ MSDN (определение метода события получателя)

Наконец, после того, как вы обнаружите обработчик от того или другого, вызовите связанный метод Invoke ().

IDispatch :: Invoke @ MSDN
IDispatchEx :: InvokeEx @ MSDN

Начальный (обработка предопределенных События MSHTML)

Большинство объектов обработчиков событий создаются вручную, так как это позволяет им принимать события MSHTML через IDispatch при получении вызовов через attachEvent () или при назначении свойствам события. Этот механизм варьируется от типичного ConnectionPointContainer до EventSink, который преобладает в COM. Однако создать объект для обработки этих событий проще. Есть несколько ключевых отличий, на которые следует обратить внимание, если вы собираетесь создать такой объект для обработки события.

  1. Первое ограничение состоит в том, что DISPID и имя метода полученного события должны совпадать с DISPID и методом для полученного события. Документация по этому поводу немного скудна, но лучшее место для определения правильного DISPID - это посмотреть файлы заголовков C ++. Если у вас установлен Microsoft Platform SDK, вы можете заглянуть в подкаталог include в файле (сокращение от MSHTML Dispatch ID). Он содержит список всех соответствующих идентификаторов отправки MSHTML.

  2. Второе ограничение заключается в том, что IE / MSHTML не вызывает двоичную версию методов, объявленных в интерфейсах на основе vtable, поэтому вызов будет поступать через IDispatch :: Invoke () . Это может быть проблемой для вас, если желаемая среда для COM не заботится о маршрутизации обоих типов вызовов к одному и тому же обработчику в вашем коде.

  3. Чтобы создать объект обработчика, вам необходимо создать объект COM, который поддерживает IUnknown, IDispatch и IObjectSafety. IUnknown неявно используется для любого из других интерфейсов, но не забывайте IObjectSafety.

  4. Специально не требуется, но ваш объект должен быть многопоточным объектом, чтобы избежать проблем с маршалингом. Поскольку вызовы направляются в IDispatch через оболочку VARIANT, вы можете столкнуться с проблемами, если выполняете действия, требующие нескольких квартир, или если вы пытаетесь использовать компоненты со свободными потоками. Большинство фреймворков создают объекты для этой модели или предлагают этот тип по умолчанию (VB6, Delphi, MFC, ATL).

Определения в заголовочном файле C ++, упомянутом выше, в точности соответствуют элементам, перечисленным в IHTMLElement. Вот один конкретный элемент, с которого можно начать.

Во-первых, событие отключения элемента HTML DOM.

Свойство onclick (IHTMLElement) @ MSDN

Мы отмечаем, что имя этого свойства - onclick. Теперь к файлу заголовка.

MSHTMDID.H @ DDART.NET

Соответствующий элемент, который нам нужен, - DISPID_EVMETH_ONCLICK (обратите внимание на эвристику здесь: Dispatch ID => Event Method => OnClick). Согласно исходному файлу, он повторно использует существующее определение посредством определения макроса.

#define DISPID_EVMETH_ONCLICK                DISPID_CLICK

Некоторые из определений перекрывают или повторно используют те же идентификаторы DISPID, которые определены для общего использования элементов управления ActiveX / OLE. DISPID_CLICK определен в OleCtl.h, поэтому давайте отправимся туда, чтобы отследить окончательное значение. Этот файл заголовка также доступен в Platform SDK и также включен по умолчанию в установки VC ++, по крайней мере, еще в VC ++ 6.0, насколько я помню.

OLECTL.H @ DDART.NET

DISPID, который мы хотим равно -600.

#define DISPID_CLICK                    (-600)

Теперь в IDL для вашего компонента вам нужно будет либо объявить метод onclick (), который имеет это значение DISPID; или вам нужно будет обработать этот DISPID в вашем обработчике для IDispatch :: Invoke (). Если вы используете ATL, не помешает объявить метод и предоставить двойной макет. Другие реализации могут отличаться.

Остальная часть вашей разработки должна быть типичной для сценариев объектов в Internet Explorer. Также обратите внимание, что большинство этих DISPID попадают в отрицательный диапазон, чтобы избежать конфликтов с пользовательскими идентификаторами DISPID.

0, насколько я помню.

OLECTL.H @ DDART.NET

Нам нужен DISPID -600.

#define DISPID_CLICK                    (-600)

Теперь в IDL для вашего компонента вам нужно будет объявить метод onclick ( ), имеющий это значение DISPID; или вам нужно будет обработать этот DISPID в вашем обработчике для IDispatch :: Invoke (). Если вы используете ATL, не помешает объявить метод и предоставить двойной макет. Другие реализации могут отличаться.

Остальная часть вашей разработки должна быть типичной для сценариев объектов в Internet Explorer. Также обратите внимание, что большинство этих DISPID попадают в отрицательный диапазон, чтобы избежать конфликтов с пользовательскими идентификаторами DISPID.

0, насколько я помню.

OLECTL.H @ DDART.NET

Нам нужен DISPID -600.

#define DISPID_CLICK                    (-600)

Теперь в IDL для вашего компонента вам нужно будет объявить метод onclick ( ), имеющий это значение DISPID; или вам нужно будет обработать этот DISPID в вашем обработчике для IDispatch :: Invoke (). Если вы используете ATL, не помешает объявить метод и предоставить двойной макет. Другие реализации могут отличаться.

Остальная часть вашей разработки должна быть типичной для сценариев объектов в Internet Explorer. Также обратите внимание, что большинство этих DISPID попадают в отрицательный диапазон, чтобы избежать конфликтов с пользовательскими идентификаторами DISPID.

или вам нужно будет обработать этот DISPID в вашем обработчике для IDispatch :: Invoke (). Если вы используете ATL, не помешает объявить метод и предоставить двойной макет. Другие реализации могут отличаться.

Остальная часть вашей разработки должна быть типичной для сценариев объектов в Internet Explorer. Также обратите внимание, что большинство этих DISPID попадают в отрицательный диапазон, чтобы избежать конфликтов с пользовательскими идентификаторами DISPID.

или вам нужно будет обработать этот DISPID в вашем обработчике для IDispatch :: Invoke (). Если вы используете ATL, не помешает объявить метод и предоставить двойной макет. Другие реализации могут отличаться.

Остальная часть вашей разработки должна быть типичной для сценариев объектов в Internet Explorer. Также обратите внимание, что большинство этих DISPID попадают в отрицательный диапазон, чтобы избежать конфликтов с пользовательскими идентификаторами DISPID.

3
ответ дан 15 December 2019 в 06:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: