2

我对多线程编程很陌生,我无法从 xelium 示例中理解如何执行 javascript 并获取返回值。我已经测试过:

browser.GetMainFrame().ExecuteJavaScript("SetContent('my Text.')", null, 0);

javascript被执行,但我这个函数不允许我获取返回值。我应该执行以下函数来获取用户在框中写入的所有文本..

browser.GetMainFrame().ExecuteJavaScript("getContent('')", null, 0);

该函数TryEval应该这样做......</p>

browser.GetMainFrame().V8Context.TryEval("GetDirtyFlag", out returninformation , out exx);

但是这个函数是不能从浏览器调用的,我想一定是从渲染器调用的吧?我该怎么做?

我无法理解关于CefRenderProcessHandlerOnProcessMessageReceived.. 如何注册 Scriptable Object 并设置我的 javascript 和参数的解释?

感谢任何建议我如何解决这个问题!

4

3 回答 3

4

我也一直在为此苦苦挣扎。我不认为有办法同步地做到这一点......或者容易:)

也许可以做的是:

  1. 从浏览器发送带有所有 JS 信息的 sendProcessMessage 到渲染器进程。您可以以结构化的方式将各种参数传递给此调用,因此按顺序封装 JS 方法名称和参数应该不难。
  2. 在渲染器进程中(RenderProcessHandler onProcessMessageReceived 方法)在 V8Context 上执行 TryEval 并通过 out 参数获取返回值并将 JS 返回值发送回浏览器进程(请注意,这支持来自您的 JS 方法的普通返回语义)。你得到onProcessMessageReceived 中的浏览器实例引用,所以就这么简单(混合伪代码)

    browser.GetMainFrame().CefV8Context.tryEval(js-code,out retValue, out exception);

    处理 retValue;

    browser.sendProcessMessage(...);

浏览器会在 onProcessMessageReceived 中的 WebClient 中获得回调。

在设置 JS 方面,这里没有什么特别之处。例如,我有一个加载的 html 页面,其中包含一个 js 函数。它接受一个参数作为输入并返回一个字符串。在 TryEval 的 js-code 参数中,我只需提供此值:

"myJSFunctionName('here I am - input param')"

这有点令人费解,但似乎是一种简洁可行的方法 - 在我看来,它比执行 ExecuteJavaScript 和通过 XHR 在自定义处理程序上发布结果要好。

我试过这个,它确实工作得很好......而且还不错,因为它都是非阻塞的。需要在浏览器进程中进行布线以正确处理响应。

这可以扩展并内置到一组类中,以将其抽象出来以用于各种调用。

看看 Xilium 演示应用程序。onProcessMessage 的大部分必要接线已经存在 - 进行全局搜索。寻找

  1. DemoRendererProcessHandler.cs - 渲染器端,这是您将调用 tryEval 的地方
  2. DemoApp.cs - 这是浏览器端,查找 sendProcessMessage - 这将启动您的 JS 调用过程。
  3. WebClient.cs - 这是浏览器端。在这里,您会收到来自渲染器的消息以及来自您的 JS 的返回值

干杯。

于 2014-08-13T10:43:16.987 回答
1

我通过对自定义方案处理程序的 ajax 调用将结果值从我的 JavaScript 函数返回给 Xilium 主机应用程序,从而解决了这个问题。根据 Xilium 的作者 fddima 的说法,这是进行 IPC 的最简单方法

您可以在Xilium 的演示应用程序中找到如何实现方案处理程序的示例。

于 2014-04-04T12:06:48.163 回答
-4

查看这篇文章:https ://groups.google.com/forum/#!topic/cefglue/CziVAo8Ojg4

using System;
using System.Windows.Forms;
using Xilium.CefGlue;
using Xilium.CefGlue.WindowsForms;

namespace CefGlue3
{
  public partial class Form1 : Form
  {
    private CefWebBrowser browser;

    public Form1()
    {
      InitializeCef();
      InitializeComponent();
    }

    private static void InitializeCef()
    {
      CefRuntime.Load();
      CefMainArgs cefArgs = new CefMainArgs(new[] {"--force-renderer-accessibility"});
      CefApplication cefApp = new CefApplication();
      CefRuntime.ExecuteProcess(cefArgs, cefApp);
      CefSettings cefSettings = new CefSettings
      {
        SingleProcess = false, 
        MultiThreadedMessageLoop = true, 
        LogSeverity = CefLogSeverity.ErrorReport, 
        LogFile = "CefGlue.log",
      };
      CefRuntime.Initialize(cefArgs, cefSettings, cefApp);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      browser = new CefWebBrowser
      {
        Visible = true,
        //StartUrl = "http://www.google.com",
        Dock = DockStyle.Fill,
        Parent = this
      };
      Controls.Add(browser);
      browser.BrowserCreated += BrowserOnBrowserCreated;
    }

    private void BrowserOnBrowserCreated(object sender, EventArgs eventArgs)
    {
      browser.Browser.GetMainFrame().LoadUrl("http://www.google.com");
    }
  }
}

using Xilium.CefGlue;

namespace CefGlue3
{
  internal sealed class CefApplication : CefApp
  {
    protected override CefRenderProcessHandler GetRenderProcessHandler()
    {
      return new RenderProcessHandler();
    }
  }

  internal sealed class RenderProcessHandler : CefRenderProcessHandler
  {
    protected override void OnWebKitInitialized()
    {
      CefRuntime.RegisterExtension("testExtension", "var test;if (!test)test = {};(function() {test.myval = 'My Value!';})();", null);
      base.OnWebKitInitialized();
    }
  }
}
于 2014-01-23T14:12:23.777 回答