在C#中使用MSHTML的高階支援介面
阿新 • • 發佈:2018-11-10
在C#中使用MSHTML的高階支援介面
原文出處 Using MSHTML Advanced Hosting Interfaces, CodeProject
下載原始碼:IDocHostUIHandler(79KB)
摘要
本文向你演示瞭如何使用IDocHostUIHandler之類MSHTML的高階介面。
概覽
本文將向你展示如何在 .NET 下使用 MSHTML 的高階支援介面,特別是其中的 IDocHostUIHandler 介面。這一系列的介面可以幫助你自由調整 Microsoft 的 Web Browser Control (Web 瀏覽控制)使用者介面。你可以在 Web Browser 中顯示個人的定製上下文選單。而我將向你演示如何使用 IDocHostUIHandler 這個介面,而不是自己重寫一個同樣的介面。額外的,我還將演示如何接收 Web 頁面中的文件( Document )元素髮出的事件。
將一個 Web Browser 控制放在一個 Form 上從而實現完整的瀏覽器功能,是一件非常輕鬆的事。但在你的應用程式裡,也許你希望能更充分地控制使用者與 Web 控制間的互動。比如當你的應用程式使用了基於 DHTML (動態 HTML )的使用者介面時, IE 的標準上下文選單便實在是配不上它了。而一個叫作 IDocHostUIHandler 的介面則能為你提供改變所有這些的能力。
實現 IDocHostUIHandler 介面
你的應用程式必須實現一個 IDocHostUIHandler 介面,之後再使用 ICustomDoc::SetUIHandler() 方法告訴 MSHTML 你已經實現並希望使用這個介面。 IDocHostUIHandler 介面包含在 Platform SDK 的 Internet Development SDK 中,並由 MsHtmlHst.IDL 所定義。
對於在 C# 中引入這些介面,我曾經見過的一種方法是手工地在原始碼中寫出其介面的定義。而我準備使用另一種方法:建立包含所需介面的型別庫來宣告它,之後再通過 TLBImp 工具建立一個 Interop 程式集。這樣你就不需要自己定義引數的封送過程了。
首先,要建立一個包含了所需介面宣告的 IDL 檔案,當然地你也需要給生成的型別庫提供一個 UUID 。該 IDL 檔案的全部內容如下(MsHtmHstInterop.idl),而我們只需要其中的一部分介面:
[ uuid(47F05070-FD66-45cc-AD99-74260F94A16B) ] library MsHtmHstInterop { import "MsHtmHst.idl"; enum tagDOCHOSTUIDBLCLK; enum tagDOCHOSTUIFLAG; enum tagDOCHOSTUITYPE; interface ICustomDoc; interface IDocHostShowUI; interface IDocHostUIHandler; interface IDocHostUIHandler2; interface IHostDialogHelper; };
下一步是利用這個 IDL 檔案,通過 MIDL 這個 Platform SDK 工具生成對應的型別庫 TLB 檔案。
midl MsHtmHstInterop.idl /tlb bin/MsHtmHstInterop.tlb接下來,我們再利用該 TLB 檔案,通過 TLBImp 工具生成對應的 Interop 程式集。
tlbimp bin/MsHtmHstInterop.tlb /out:bin/MsHtmHstInterop.dll現在我們就可以在我們的 C# 程式裡直接通過一個 using 語句使用這個程式集來訪問這些介面了。
using MsHtmHstInterop; //節選自HtmlUI.cs實現
在這個演示程式裡,我將在 Form 上放置一個 Web Browser 控制,並由該 form 類實現 IDocHostUIHandler 介面。
要將 IDocHostUIHandler 的個人實現掛接到 MSHTML 上,我們首先需要獲得 ICustomDoc 介面,然後再將個人實現的 IDocHostUIHandler 介面作為引數,呼叫 ICustomDoc 介面的 SetUIHandler() 方法。
//節選自HtmlUI.cs中HtmlUIForm的constructor public HtmlUIForm() { InitializeComponent(); this.WebBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.WebBrowser_DocumentComplete); object flags = 0; object targetFrame = String.Empty; object postData = String.Empty; object headers = String.Empty; this.WebBrowser.Navigate("about:blank", ref flags, ref targetFrame, ref postData, ref headers); ICustomDoc cDoc = (ICustomDoc)this.WebBrowser.Document; cDoc.SetUIHandler((IDocHostUIHandler)this); this.WebBrowser.Navigate(@"res://HtmlUI.exe/Sample1.htm", ref flags, ref targetFrame, ref postData, ref headers); }以上就是所有要做的了。當然地, form 必須實現 IDocHostUIHandler 介面的所有方法。
資源裡的 HTML 檔案
也許你注意到了,在我的程式碼裡使用了一個資源: protocol 。這是一個簡易方法,用以將 HTML 檔案及其他的支援檔案打包進你的 EXE 檔案中。這種方法還有幾個優點:使用者無法輕易地更改你的應用程式介面;你也不必為把其他的檔案打包進你的安裝程式包裡大費周張。你所要做的僅是建立一個資源定義檔案 :HtmlUI.rc
Sample1.htm HTML "Sample1.htm"之後它會被編譯為一個 RES 檔案,然後你再通過 /win32res 這個編譯開關將該 RES 檔案加入你的程式集中。
處理文件事件
如果你的應用程式擁有一個基於 DHTML 的使用者介面,那你需要捕捉頁面中元素髮出的事件,以使其功能更完善。在你執行我這個演示程式時,將會看到:當點選頁面中的按鈕後,會彈出一個訊息對話方塊,這個對話方塊是從 C# 應用程式中觸發的,而非頁面中的指令碼。以下即是其程式碼:
//節選自HtmlUI.cs private void WebBrowser_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e) { // 獲取文件物件 IHTMLDocument2 doc = (IHTMLDocument2)this.WebBrowser.Document; // 獲取按鈕的一個引用reference HTMLButtonElement button = (HTMLButtonElement)doc.all.item("theButton", null); // 將事件處理器通過事件介面進行繫結 ((HTMLButtonElementEvents2_Event)button).onclick += new HTMLButtonElementEvents2_onclickEventHandler(this.Button_onclick); } private bool Button_onclick(IHTMLEventObj e) { MessageBox.Show("Alert from the app: Received theButton.onclick!"); return true; }生成應用程式
我已經把一個 Make 檔案包括在原始碼包裡了,這樣你可以在命令列方式下通過 NMake 命令列工具生成本文的這個演示程式。注意 TLBImp MsHtml.TLB 這步可能會多要點時間才能完成。