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;
}