原文出处 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 文件中,我已经包括了 MSHTML 所有的高级支持接口及其枚举类型。
midl MsHtmHstInterop.idl /tlb bin\MsHtmHstInterop.tlb接下来,我们再利用该 TLB 文件,通过 TLBImp 工具生成对应的 Interop 程序集。
tlbimp bin\MsHtmHstInterop.tlb /out:bin\MsHtmHstInterop.dll现在我们就可以在我们的 C# 程序里直接通过一个 using 语句使用这个程序集来访问这些接口了。
using MsHtmHstInterop; //节选自HtmlUI.cs实现
//节选自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 接口的所有方法。
Sample1.htm HTML "Sample1.htm"之后它会被编译为一个 RES 文件,然后你再通过 /win32res 这个编译开关将该 RES 文件加入你的程序集中。
//节选自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; }生成应用程序