IE中的.NET ActiveX组件-如何获取浏览器参考
时间:2020-03-05 18:55:53 来源:igfitidea点击:
我承认我对COM和IE架构了解得足够多,只是很危险。我有一个与此相似的有效的C.NET ActiveX控件:
using System; using System.Runtime.InteropServices; using BrowseUI; using mshtml; using SHDocVw; using Microsoft.Win32; namespace CTI { public interface CTIActiveXInterface { [DispId(1)] string GetMsg(); } [ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)] public class CTIActiveX : CTIActiveXInterface { /*** Where can I get a reference to SHDocVw.WebBrowser? *****/ SHDocVw.WebBrowser browser; public string GetMsg() { return "foo"; } } }
我使用regasm注册并创建了一个类型库:
regasm CTIActiveX.dll /tlb:CTIActiveXNet.dll /codebase
并可以在javascript中成功实例化此代码:
var CTIAX = new ActiveXObject("CTI.CTIActiveX"); alert(CTIAX.GetMsg());
如何在CTIActiveX中获得对客户端站点(浏览器窗口)的引用?我已经在BHO中通过实现IObjectWithSite做到了这一点,但是我认为这不是ActiveX控件的正确方法。如果我尝试在Javascript中实例化时在CTIActiveX上实现任何接口(我的意思是类似IObjectWithSite的COM接口),则会收到错误消息,该对象不支持自动化。
解决方案
回答
首先,界面需要ComVisible(true)才能被调用脚本看到(这可能会导致错误)。
其次,在项目中将一个.NETreference添加到" Microsoft.mshtml"。这将为各种与IE相关的内容(Windows,HTML文档等)导入COM接口。
然后,我们需要向接口添加IHtmlDocument2类型的属性:
IHtmlDocument2 Document { set; }
...在课程中实现:
public IHtmlDocument2 Document { set { _doc = value;} }
...从脚本中调用
CTIAX.Document = document;
...一旦存储了对文档的引用,就可以随意使用它来到达窗口,其他框架或者所需的HTML DOM的任何部分。
回答
我找到了可行的解决方案。这不是理想的,因为它依赖于IE窗口的位置URL匹配来获取正确的容器,但是它确实可以工作。就我而言,我在查询字符串上使用特殊值以确保获得正确的窗口。
这将获得对SHDocVw.InternetExplorer的引用,它公开了与SHDocVw.WebBrowser相同的GetProperty和PutProperty:
private InternetExplorer GetIEWindow(string url) { SHDocVw.ShellWindowsClass sh = new ShellWindowsClass(); InternetExplorer IE; for (int i = 1; i <= sh.Count; i++) { IE = (InternetExplorer)sh.Item(i); if (IE != null) { if (IE.LocationURL.Contains(url)) { return IE; } } } return null; }