2011-02-10 63 views
2

我使用C#4.0中的MSHTML API,運行代碼的後勤不成問題。然而,編寫代碼由於MSHTML和/或COM接口的設計方式而引起的痛苦。具體而言,當應該有一個時,沒有界面層次結構。例如,IHTMLDocument7不延伸IHTMLDocument6,它不延伸IHTMLDocument5等等(儘管如此,IHTMLDocument2確實延伸IHTMLDocument)。處理kludgy界面層次結構(MSHTML)的最佳方法是什麼?

進一步混淆事項有擴展DispHTMLDocument(其所有的IHTMLDocument*接口的方法)和HTMLDocumentEvents_EventHTMLDocument接口(其中包含有一些,但不是所有的事件)。爲了增加混亂,HTMLDocumentClass是一個coclass,它實現了上述所有接口,然後是一些接口,如IDocumentSelectorHTMLDocumentEvents4_Event

我真的很希望能夠與HTMLDocumentClass的API來工作,但嘗試投放到它給了我:

System.InvalidCastException:無法類型 「MSHTML的 投COM對象.HTMLDocumentClass'到類 鍵入'mshtml.HTMLDocumentClass'。 代表COM 組件的類型實例不能轉換爲表示COM組件的不同類型 ; 然而只要底層COM 組件支持QueryInterface 調用接口的IID,它們就可以轉換爲接口 。

另外,一些接口沒有關聯的coclass;例如有IHTMLElement*接口,但沒有HTMLElement接口,也沒有HTMLElementClass類。總的來說,我發現很難編程到界面。

有沒有好的技術與這個接口訓練失敗,或者我應該放棄智能感知和使用dynamic無處不在?我考慮編寫實現所有接口的包裝類,但是有很多MSHTML接口,每個接口都有大量的成員,所以實際的解決方案必須實現自動化。

+0

由於您沒有使用PIA,因此您將收到無效的轉換異常。一切都從這裏崩潰。 – 2011-02-10 00:59:51

+0

我從IE9的TLB文件生成了一個DLL,因爲我想要一個理智的DOM API。我試過參考標準的mshtml.dll(文件版本9.00),但是我的項目最終引用了GAC中的7.0版本。 – ide 2011-02-10 01:43:03

回答

1

IHTMLDocument6不延長IHTMLDocument5

即使延長IHTMLDocument5,每COM規則,你還是應該的QueryInterface得到IHTMLDocument5,不要使用繼承。我很高興他們沒有讓你懷疑你如何能夠爲QI提供一個已經被包裝類實現的接口作爲繼承的副作用。

我建議你不要使用任何包裝類,並在控制對象時切換到向後兼容的接口。基於錯誤消息,爲IE生成的COM包裝器CLR看起來像來自不同程序集的mshtml.HTMLDocumentClass類。

在COM編程中,您會經常看到工廠模式。對於html元素對象,工廠方法是IHTMLDocument2.createElement。通常,如果作者選擇使用此模式,則無法自行創建對象。

Visual Studio會自動引用PIA(如果存在),否則它會使用tlbexp。exe來生成以「Interop」爲前綴的互操作程序集。然而,大多數時候你會在PIA中使用一些接口,所以你可以編寫自己的interop類型(或者從谷歌代碼搜索中複製)並獲得這個大型程序集。

相關問題