【问题标题】:Sending information from Chromium Embedded (Javascript) to a containing C++ application将信息从 Chromium Embedded (Javascript) 发送到包含 C++ 的应用程序
【发布时间】:2013-09-20 22:43:47
【问题描述】:

查看 Chromium Embedded Framework 示例后,我有一个问题。我需要与窗口的嵌入式部分进行本机交互。但是,在 CEF 示例中,我看到的只是 c++ 向浏览器发送消息,而不是相反。我想知道是否有任何方法可以从 c++ 中的 JavaScript 发送消息,例如函数的方式。

我正在寻找的是这样的东西。我的网页中有一个按钮,单击该按钮。我想最小化窗口。有什么方法可以在 CEF 中从 JavaScript 调用一些 c++ 吗?

【问题讨论】:

标签: javascript c++ chromium-embedded


【解决方案1】:

如果有人需要一个例子,这是我做到的一种方式:

  1. 确定您希望使用的自定义“协议” 这是一个作为宏字符串的示例 #define PROTO_MYAPPCOMMAND "myapp://"

  2. 在您的自定义 CefApp 类(继承自 CefApp 的类)上, 也继承自 CefRenderProcessHandler。

  3. 实现 OnBeforeNavigation() 函数:

    //declare (i.e. in header) 
    virtual bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser, 
        CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, 
        NavigationType navigation_type, bool is_redirect)  OVERRIDE; 
    
    //implementation 
    bool CClientApp::OnBeforeNavigation(CefRefPtr<CefBrowser> browser, 
        CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, 
        NavigationType navigation_type, bool is_redirect)
    {
        CefString cefval = request->GetURL(); 
        CString csval = cefval.c_str(); 
    
        if (csval.Find(PROTO_MYAPPCOMMAND, 0) == 0)
        {
            //process the command here 
    
            //this is a command and not really intended for navigation 
            return true; 
        }
    
        return false; //true cancels navigation, false allows it 
    }
    

以下是添加“退出”应用按钮的示例:

在cpp中

    #define STR_COMMANDAPPEXIT _T("command.appexit")
    bool CClientApp::OnBeforeNavigation(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, NavigationType navigation_type, bool is_redirect)
    {
        CefString cefval = request->GetURL(); 
        CString csval = cefval.c_str(); 

        if (csval.Find(PROTO_MYAPPCOMMAND, 0) == 0)
        {
            CString command = url; 
            command.Replace(PROTO_MYAPPCOMMAND, _T("")); 

            if (command.Find(STR_COMMANDAPPEXIT, 0) == 0) 
            {
                ::PostMessage(hwnd, WM_CLOSE, NULL, NULL); 
            }

            //this is a command and not really intended for navigation 
            return true; 
        }

        return false; //true cancels navigation, false allows it 
    }

还为所有操作创建了一个 js 实用程序文件以简化调用它们

    var MYHOST = MYHOST || {};
    /// Exit the Application (host app) 
    MYHOST.ExitApp = function() {
        window.location = 'myapp://command.appexit';
    };

在页面js中(即在按钮/div点击中)

    <div class="exitbutton" onclick="MYHOST.ExitApp();">Exit</div>

如果需要传入参数,只需在js中的url中追加并解析即可 cpp 中的字符串,如下所示:

    MYHOST.DoSomething = function() {
        window.location = 'myapp://command.dosomething?param1=' + value1 + "&param2=" + value2 + "&param3=" + value3;
    };

注意:我已经简化了代码,但请添加验证等

希望这会有所帮助!

【讨论】:

  • 谢谢!这是我见过的关于如何做到这一点的最佳示例,尽管它不是通过典型的 url 方案处理程序。
  • 但它会是同步的,会冻结你的浏览器渲染直到事件处理完毕
【解决方案2】:

一个没有严肃的方法来做到这一点,只需要一行代码:

Console.Log('. ...') 在您需要发送到应用程序的字符串/数据结构前面带有一个前导 ESC 字符。 只需实现'OnConsoleMessage'并根据前导或非ESC char触发准确的工作。

PS:我不得不在 2015 年使用这个棘手的解决方案,因为 DCEF3 版本对于方案处理程序的使用存在错误。

对于严肃的工作:注册自定义方案处理程序很好。

【讨论】:

  • 这是我在 stackoverflow 上见过的“最骇人听闻”的解决方案之一!
  • 啊哈哈哈哈哈哈哈
【解决方案3】:

最简单的方法: 1. 在主进程(UI 进程) - 您可以创建自己的自定义方案处理程序(它也可以绑定到 http 协议,并且可以通过域来区分处理程序)。 2. 从 JS 端,您可以使用 XMLHttpRequest 调用您的方案处理程序。这是JS主进程之间IPC的标准机制。

其他方式: 使用 V8 绑定,但在这种情况下,您需要在渲染器和主进程之间创建自己的 IPC。或者使用内置的 IPC,但注意它只能以异步方式发送消息。

【讨论】:

  • 谢谢!您知道有关内置 IPC 的任何示例或教程吗?我可以在铬中找到 IPC 的示例,但不知道它是否在 CEF 中是如何工作的。我假设它支持 CEF 类型 3,对吗?
  • 好的,在查看了更多选项之后,注册自定义方案处理程序看起来是一个不错的选择,但是,就像 CEF 中的许多东西一样,我似乎找不到任何示例。 groups.google.com/forum/#!msg/cefglue/GmUdlO-qA-w/2Jcnxp75ynUJ 是一个很好的例子,但是它在 c# 中并使用了几个 c++ 中不可用的类。有没有什么网站或例子可以解释注册和阅读消息的过程
  • 我不确定我是否正确理解你。这都是关于 CEF3 的。内置 IPC 围绕 CefBrowser.SendProcessMessage 生活,您可以在 CefClient.OnProcessMessageReceived 和 CefRenderProcessHandler.OnProcessMessageReceived 处处理它们。 C++和Xilium.CefGlue都包含简单示例,搜索用法即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 2017-10-22
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
相关资源
最近更新 更多