从Chromium Embedded(Javascript)发送信息到包含的C ++应用程序

10

在查看了Chromium嵌入式框架示例之后,我有一个问题。我需要与窗口的嵌入式部分进行本地交互。然而,在CEF示例中,我只看到了c++向浏览器发送消息,没有相反的情况。 我想知道是否有办法从JavaScript中向c++发送消息,就像使用函数一样。

我正在寻找的是这样的东西。我在网页中有一个按钮,当单击时,我希望最小化窗口。在CEF中,有没有办法从JavaScript调用一些c++?


请查看我在此帖子中的评论(已链接)...http://stackoverflow.com/questions/18225261/xilium-cefglue-how-to-execute-javascript-with-return-value。这可能对您有所帮助... - Moonwalker
3个回答

14
如果有人需要例子,以下是我做过的一种方式:
  1. Determine the custom 'protocol' you wish to use here's an example as a macro string #define PROTO_MYAPPCOMMAND "myapp://"

  2. On your custom CefApp class (the one inheriting from CefApp), also inherit from CefRenderProcessHandler.

  3. implement the OnBeforeNavigation() function:

    //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方案处理程序完成的。 - joshua-anderson
1
但它将是同步的,会冻结您的浏览器渲染,直到事件被处理。 - Anil8753

13

有一种不严谨的方法可以实现此操作,只需要一行代码:

在您需要发送到应用程序的字符串/数据结构前面加上ESC字符,然后使用Console.Log('. ...')。只需实现“OnConsoleMessage”并根据是否有前导ESC字符触发准确的工作。

注:我在2015年不得不使用这种巧妙的解决方案,因为DCEF3版本在方案处理程序使用方面存在错误。

对于重要工作:注册自定义方案处理程序就可以了。


6
这是我在stackoverflow上见过的最“hacky”的解决方案之一! - Tim
啊哈哈哈哈 啊哈哈哈哈 - Researcher

9
最简单的方法: 1. 在主进程(UI进程)中,您可以创建自己的自定义方案处理程序(它也可以绑定到http协议,并通过域区分处理程序)。 2. 从JS侧面,您可以使用XMLHttpRequest调用您的方案处理程序。这是JS<>Main进程之间IPC的标准机制。
另一种方法: 使用V8绑定,但在这种情况下,您需要自己在渲染器和主进程之间进行IPC。或者使用内置IPC,但请注意,它仅以异步方式发送消息。

1
谢谢!你知道有关内置IPC的任何示例或教程吗?我可以在Chromium中找到IPC的示例,但完全不知道它是否适用于CEF。我假设它支持CEF类型3,正确吗? - joshua-anderson
1
好的,经过更深入的了解,注册自定义方案处理程序似乎是一个不错的选择,但是,像CEF中的许多东西一样,我似乎找不到任何示例。https://groups.google.com/forum/#!msg/cefglue/GmUdlO-qA-w/2Jcnxp75ynUJ 是一个很好的例子,但它是用c#编写的,并使用了在c++中不可用的几个类。是否有任何网站或示例可以解释注册和读取消息的过程? - joshua-anderson
2
我不确定我是否正确理解了你的意思。这都与CEF3有关。 内置IPC围绕CefBrowser.SendProcessMessage存在,您可以在CefClient.OnProcessMessageReceived和CefRenderProcessHandler.OnProcessMessageReceived中处理它们。C++和Xilium.CefGlue都包含简单的示例,只需搜索用法即可。 - Dmitry Azaraev

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