我承认我对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中获取对客户端站点(浏览器窗口)的引用?我通过实现IObjectWithSite在BHO中完成了这个,但我不认为这是ActiveX控件的正确方法。当我尝试在Javascript中实例化时,如果我在CTIActiveX上实现任何接口(我的意思是像IObjectWithSite这样的COM接口),我得到一个错误,该对象不支持自动化。
答案 0 :(得分:3)
首先,您的接口需要ComVisible(true)才能被调用脚本看到(这可能导致错误)。
其次,将项目中的.NETreference添加到“Microsoft.mshtml”。这将导入各种与IE相关的东西(窗口,HTML文档等)的COM接口
然后,您需要将IHtmlDocument2类型的属性添加到您的界面:
IHtmlDocument2 Document { set; }
...在班上实施:
public IHtmlDocument2 Document
{
set { _doc = value;}
}
...从脚本
调用它CTIAX.Document = document;
...一旦存储了对文档的引用,就可以随意使用它来到窗口,其他框架或HTML DOM的任何部分。
答案 1 :(得分:1)
我找到了一个可行的解决方案。它不是理想的,因为它依赖于匹配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;
}
答案 2 :(得分:0)
有一种简单而清洁的方法:
public void GetBrowser()
{
ShellWindows m_IEFoundBrowsers = new ShellWindows();
foreach (InternetExplorer Browser in m_IEFoundBrowsers)
{
webBrowser = (SHDocVw.WebBrowser) Browser;
// do what you want ...
}
}