我承认我对COM和IE架构了解得足够多,只是很危险。 我有一个工作的C#.NET ActiveX控件,类似于此:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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注册并创建了一个类型库:
1
| regasm CTIActiveX.dll /tlb:CTIActiveXNet.dll /codebase |
并可以在javascript中成功实例化此代码:
1 2
| var CTIAX = new ActiveXObject("CTI.CTIActiveX");
alert(CTIAX.GetMsg()); |
如何在CTIActiveX中获得对客户端站点(浏览器窗口)的引用? 我已经在BHO中通过实现IObjectWithSite做到了这一点,但我认为这不是ActiveX控件的正确方法。 如果我尝试在Javascript中实例化时在CTIActiveX上实现了任何接口(我的意思是类似IObjectWithSite的COM接口),则会收到错误消息,该对象不支持自动化。
首先,您的界面需要ComVisible(true)才能被调用脚本看到(这可能会导致错误)。
其次,在您的项目中向.Microsoft.mshtml添加一个.NETreference。这将为各种与IE相关的内容(Windows,HTML文档等)导入COM接口。
然后,您需要将IHtmlDocument2类型的属性添加到您的接口:
1
| IHtmlDocument2 Document { set; } |
...在您的课程中实现:
1 2 3 4
| public IHtmlDocument2 Document
{
set { _doc = value;}
} |
...从脚本中调用
1
| CTIAX.Document = document; |
...一旦您存储了对文档的引用,就可以随意使用它来到达窗口,其他框架或所需的HTML DOM的任何部分。
我找到了可行的解决方案。这不是理想的方法,因为它依赖于IE窗口的位置URL匹配来获取正确的容器,但是它确实可以工作。就我而言,我在查询字符串上使用特殊值以确保获得正确的窗口。
这将获得对SHDocVw.InternetExplorer的引用,它公开了与SHDocVw.WebBrowser相同的GetProperty和PutProperty:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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;
} |
有一个简单而干净的方法可以做到这一点:
1 2 3 4 5 6 7 8 9 10 11 12
| public void GetBrowser()
{
ShellWindows m_IEFoundBrowsers = new ShellWindows();
foreach (InternetExplorer Browser in m_IEFoundBrowsers)
{
webBrowser = (SHDocVw.WebBrowser) Browser;
// do what you want ...
}
} |