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

jos*_*son 10 javascript c++ chromium-embedded

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

我正在寻找的是这样的.点击后,我的网页上有一个按钮.我想尽量减少窗口.有没有办法在CEF中用JavaScript调用一些c ++?

mic*_*cks 14

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

  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 
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

在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 
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

    <div class="exitbutton" onclick="MYHOST.ExitApp();">Exit</div>
Run Code Online (Sandbox Code Playgroud)

如果你需要传入参数,只需将它们附加到js的url中并解析cpp中的字符串,如下所示:

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

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

希望这可以帮助!


Gaë*_*ERE 12

没有认真的方法,需要一行代码:

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

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

对于认真工作:注册自定义方案处理程序是好的.

  • 这是我在stackoverflow上见到的"最讨厌的"解决方案之一! (4认同)

Dmi*_*aev 9

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

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

  • 我不确定我是否正确理解你.这完全是关于CEF3.内置的IPC存在于CefBrowser.SendProcessMessage中,您可以在CefClient.OnProcessMessageReceived和CefRenderProcessHandler.OnProcessMessageReceived处理它们.C++和Xilium.CefGlue都包含简单的示例,只包含搜索用法. (2认同)