在IE中使用.NET ActiveX组件 - 如何获取浏览器引用

6

我承认自己对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控件的正确方法。如果我在CTIActiveX上实现任何接口(我的意思是COM接口,比如IObjectWithSite),当我尝试在Javascript中实例化时,会出现对象不支持自动化的错误。

3个回答

4

首先,您的接口需要添加ComVisible(true)才能被调用脚本看到(这可能导致错误)。

其次,在项目中添加对“Microsoft.mshtml”的.NET引用。这将导入与IE相关事物(窗口、HTML文档等)的COM接口

然后,您需要向接口添加一个类型为IHtmlDocument2的属性:

IHtmlDocument2 Document { set; }

...在你的类中实现它:

public IHtmlDocument2 Document
{
  set { _doc = value;}
}

...从脚本中调用它

CTIAX.Document = document; 

一旦您存储了对文档的引用,就可以随意使用它来访问窗口、其他帧或希望访问的HTML DOM的任何部分。


好的答案帮助了我解决另一个问题;然而它并不完全符合我的要求。IHTMLDocument2.parentWindow 返回的是 mshtml.IHTMLWindow2,而不是 SHDocVw.WebBrowser。我正在寻找 SHDocVw.WebBrowser,以便我可以使用 GetProperty 和 PutProperty 方法与 BHO 进行通信。 - Brian Leahy
另外,需要明确的是,问题中的示例确实有效。如果实现类像我的示例一样指定了ComVisible,则似乎不需要使用ComVisible(true)。只有在显式实现COM接口(如IObjectWithSite)时才会出现问题。 - Jonas Follesø

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

1
你最开始是怎么获取那个URL的? - Rick Minerich

0

有一种简单而更清晰的方法来实现它:

public void GetBrowser()
        {

            ShellWindows m_IEFoundBrowsers = new ShellWindows();

            foreach (InternetExplorer Browser in m_IEFoundBrowsers)
            {
                webBrowser = (SHDocVw.WebBrowser) Browser;
                 // do what you want ...
            }

        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接