在查看Chromium Embedded Framework示例后,我有一个问题。我需要与窗口的嵌入部分进行本机交互。但是,在CEF示例中,我看到的只是c ++向浏览器发送消息,而不是相反。我想知道是否有任何方法可以从c ++发送来自JavaScript的消息,就像函数一样。
我要找的是这样的。点击后,我的网页上有一个按钮。我想尽量减少窗口。有没有办法在CEF中用JavaScript调用一些c ++?
答案 0 :(得分:14)
如果有人需要一个例子,这是我做的一种方式:
确定您要使用的自定义“协议” 这是一个宏字符串的例子 #define PROTO_MYAPPCOMMAND“myapp://”
在您的自定义CefApp类(继承自CefApp的类)上, 也继承自CefRenderProcessHandler。
实现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
}
以下是添加“退出”应用按钮的示例:
in 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 + "¶m2=" + value2 + "¶m3=" + value3;
};
注意:我已经简化了代码,但请添加验证等
希望这有帮助!
答案 1 :(得分:12)
没有认真的方法,需要一行代码:
Console.Log(&#39;。...&#39;)在您需要发送到应用程序的字符串/数据结构前面有一个前导ESC字符。 只需实施&#39; OnConsoleMessage&#39;并根据引导或不引导ESC char来触发准确的工作。
PS:我不得不在2015年使用这个棘手的解决方案,因为DCEF3版本对于使用方案处理程序来说是错误的。对于认真的工作:注册自定义方案处理程序很好。
答案 2 :(得分:9)
最简单的方法: 1.在主进程(UI进程)中 - 您可以创建自己的自定义方案处理程序(它也可以绑定到http协议,并通过域绑定不同的处理程序)。 2.从JS方面,您可以使用XMLHttpRequest来调用方案处理程序。它是JS&lt;&gt; Main process之间IPC的标准机制。
其他方式: 使用V8绑定,但在这种情况下,您需要在渲染器和主进程之间创建自己的IPC。或者使用内置IPC,但请注意它只是以异步方式发送消息。