代码之家  ›  专栏  ›  技术社区  ›  Brian Lyttle

WinForms-如何从WebBrowser控件内部执行C应用程序代码?

  •  4
  • Brian Lyttle  · 技术社区  · 16 年前

    我有一个包含Web浏览器控件的表单。此浏览器控件将从磁盘加载一些HTML并显示它。我想在表单的HTML访问C代码中有一个按钮。

    例如,HTML中的按钮可能调用表单上的close()方法。

    目标平台:C和Windows窗体(任何版本)

    6 回复  |  直到 13 年前
        1
  •  9
  •   kÍ©eÍ£mÍ®pÍ¥ Í©    16 年前

    看看 WebBrowser.ObjectForScripting 财产。设法让google maps使用它与Windows窗体应用程序对话。

        2
  •  18
  •   Ash    16 年前

    我在过去的一些应用程序中已经实现了这一点,方法如下:(注意:下面的示例还没有准备好生产,应该只作为指南使用)。

    首先创建一个普通的.NET类(public),该类包含希望从Web浏览器控件中运行的javasvcipt调用的公共方法。

    最重要的是,它必须使用System.Runtime.InteropServices命名空间中的comVisible(true)]属性进行修饰(IE中的javascript基于COM)。它可以被称为任何东西,我称之为“外部的”,以使事情更清楚。

    using System.Runtime.InteropServices;
    
    [ComVisible(true)]
    public class External
    {
        private static MainWindow m_mainWindow = null;
    
        public External(MainWindow mainWindow)
        {
            m_mainWindow = mainWindow; 
        }
    
        public void CloseApplication()
        {
            m_mainWindow.Close();
        }
    
    
        public string CurrentDate(string format)
        {
            return DateTime.Now.ToString(format);  
        }
    }
    

    接下来,在包含Web浏览器控件的.NET窗体中创建ComVisible类的实例,然后将Web浏览器控件对象设置为该实例的脚本:

        private void MainWindow_Load(object sender, EventArgs e)
        {
             m_external = new External(this);
    
             browserControl.ObjectForScripting = m_external; 
        }
    

    最后,在Web浏览器控件中运行的javascript中,您可以通过window.external对象访问.net方法。在本例中,window.external实际上引用(通过COM互操作包装器间接引用)上面创建的“external”对象:

    // Javascript code
    function CloseButton_Click()
    {
        if (window.external)
        {
            window.external.CloseApplication();
        }
    }
    

    请注意,从javascript到.NET的调用会通过COM互操作层,因此必须查询默认接口、整理参数等。换句话说,它可能相对较慢,因此,如果您计划进行多个调用(例如,从一个循环中进行调用),请执行一些性能测试。

    另外,为了将来参考,从.NET调用javascript代码更简单,只需使用document.invokescript方法:

        browserControl.Document.InvokeScript("jScriptFunction", new object[] { "param1", 2, "param2" });
    
        3
  •  2
  •   Loris    16 年前

    我在VB6中所做的:

    • 在HTML文档中添加一堆自定义的标签,将它们的href设置为对您有意义的内容,如“closeform”
    • 在beforenavigate方法中,检查浏览器尝试转到的地址并相应地执行操作。然后取消浏览器导航。
        4
  •  0
  •   Community CDub    8 年前

    您所要做的就是为WebBrowser的导航事件添加一个事件处理程序。

    此事件将在浏览器导航到下一页之前激发。它允许您中断进程并做任何您想做的事情,包括取消导航和调用代码。

    很容易使用。我遇到的唯一警告是你不能查看postdata——请看我的问题: PostData Question

    下面是一些示例代码:

        private void MyMethod()
        {
            // do something
        }
    
        private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            MyMethod();
            e.Cancel = true;
        }
    
        5
  •  0
  •   Tim Cooper    13 年前

    这是可能的,但我在.NET中没有做到。 几年前,我有一个C++应用程序,它承载了一个Web浏览器控件(ActiveX)。从控件中的HTML,可以调用ActiveX控件并让它执行操作。

    在.NET中也是如此,尽管HTML DOM/javascript不知道C。但是,如果将.NET功能包装在COM对象中,则应该能够调用COM/ActiveX对象上的方法,而这些方法反过来又会调用C代码。

    希望这有帮助。

        6
  •  0
  •   Matthew Skelton    13 年前

    几年前我做了这个,并在这里写了博客:

    http://matthewskelton.wordpress.com/2007/04/21/calling-javascript-from-c/

    具体来说,您可以使用 Type.InvokeMember() 从C调用javascript。