Каков наилучший способ иметь дело с иерархиями интерфейса kludgy (MSHTML)? - PullRequest
2 голосов
/ 10 февраля 2011

Я использую MSHTML API из C # 4.0 и логистика выполнения кода не проблема. Написание кода, однако, является проблемой из-за того, как спроектированы интерфейсы MSHTML и / или COM. В частности, нет никакой иерархии интерфейса, когда она должна быть. Например, IHTMLDocument7 не расширяет IHTMLDocument6, что не расширяет IHTMLDocument5 и т. Д. (IHTMLDocument2 расширяет IHTMLDocument, хотя).

Для дальнейшего запутывания вопросов существует интерфейс HTMLDocument, который расширяет DispHTMLDocument (который имеет все методы интерфейсов IHTMLDocument*) и HTMLDocumentEvents_Event (который предоставляет некоторые, но не все, события). Чтобы добавить в беспорядок, HTMLDocumentClass является классом, который реализует все вышеупомянутые интерфейсы, а затем некоторые, такие как IDocumentSelector и HTMLDocumentEvents4_Event.

Мне бы очень хотелось иметь возможность работать с API HTMLDocumentClass, но попытка привести к нему дала мне:

System.InvalidCastException: невозможно литой COM-объект типа 'mshtml.HTMLDocumentClass' в класс введите «mshtml.HTMLDocumentClass». Экземпляры типов, представляющих COM компоненты не могут быть приведены к разным типы, которые представляют компоненты COM; однако они могут быть приведены к интерфейсам до тех пор, пока основной COM компонент поддерживает QueryInterface вызывает IID интерфейса.

Кроме того, некоторые интерфейсы не имеют связанного кокласса; например, есть IHTMLElement* интерфейсы, но нет ни интерфейса HTMLElement, ни класса HTMLElementClass. В целом, мне сложно программировать на интерфейс.

Существуют ли хорошие методы борьбы с этим интерфейсом, или мне стоит отказаться от IntelliSense и использовать dynamic везде? Я рассмотрел написание классов-оболочек, в которых реализованы все интерфейсы, но интерфейсов MSHTML так много, и каждый из них имеет массу членов, поэтому практическое решение необходимо автоматизировать.

1 Ответ

1 голос
/ 10 февраля 2011

IHTMLDocument6 не расширяет IHTMLDocument5

Даже если он расширяет IHTMLDocument5, согласно правилам COM, вы все равно должны QueryInterface для получения IHTMLDocument5, а не использовать наследование.Я рад, что они не позволили вам задаться вопросом, как можно использовать QI для интерфейса, который уже реализован классом-оболочкой как побочный эффект наследования.

Я предлагаю вам не использовать ни один из классов-оболочек и переключаться на обратно совместимые интерфейсы, когда вы управляете объектами.CLR оболочки COM, сгенерированный для IE, выглядит как класс mshtml.HTMLDocumentClass из другой сборки на основе сообщения об ошибке.

В программировании COM вы бы часто видели фабричный шаблон.Для объекта html-элемента фабричным методом является IHTMLDocument2.createElement.Обычно вы не можете создать объект самостоятельно, если автор решит использовать этот шаблон.

Visual Studio будет автоматически ссылаться на PIA, если таковой существует, в противном случае он использует tlbexp.exe для создания сборки взаимодействия с префиксом "Interop".».Однако большую часть времени вы будете использовать несколько интерфейсов в PIA, чтобы вы могли писать свои собственные типы взаимодействия (или копировать из Google Code Search) и получать удовольствие от этой большой сборки.

...