最近我一直试图将我的应用程序绑定到CEF,这个过程很慢,但我在最后几天取得了一些进展。但是有一件事我无法开始工作。
我想要达到的目标是: 1.在Javascript中注册回调函数(当我的应用程序中发生事件时,将调用这些函数) 2.保存回调。 3.事件发生时,执行已注册的回调。
现在我已经完成了第1步和第2步,但第3步是问题所在。 我首先通过注册回调然后在Javascript中使用executeCallback()函数调用它来测试它并且它工作。但每当我尝试从C ++中执行回调时,它都无法正常工作。
我在onContextCread()
中创建了setEventCallbackCefRefPtr<CefV8Value> object = context->GetGlobal();
CefRefPtr<CefV8Value> simplixObj = CefV8Value::CreateObject(NULL);
object->SetValue("simplix", simplixObj, V8_PROPERTY_ATTRIBUTE_NONE);
func = CefV8Value::CreateFunction("setEventCallback", $simplixHandler);
simplixObj->SetValue("setEventCallback", func, V8_PROPERTY_ATTRIBUTE_NONE);
$ simplixHandler是我自己的处理程序的一个实例。 这是我的处理程序中的setEventCallback:
bool SimplixHandler::setEventCallback(CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception)
if (arguments.size() == 2 && arguments[0]->IsString() && arguments[1]->IsFunction()) {
//Get name of callback
std::string callbackName = arguments[0]->GetStringValue();
//Get the current context
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
//Insert into callbacks
$callbacks[callbackName] = std::make_pair(context, arguments[1]);
return true;
}
else if(arguments.size() != 2) {
exception = CefString("Invalid amount of parameters. Expected 2, received " + arguments.size());
return false;
}
else {
exception = CefString("Incompatible parameter types, expected (string, function).");
return false;
}
然后我尝试通过调用executeCallback来执行回调:
bool SimplixHandler::executeCallback(std::string name, CefRefPtr<CefListValue> list) {
bool handled = false;
if (!$callbacks.empty() && $callbacks.count(name) != 0) {
std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value>> pair = $callbacks[name];
CefRefPtr<CefV8Context> context = pair.first;
CefRefPtr<CefV8Value> func = pair.second;
context->Enter();
CefV8ValueList callArgs;
//First argument is function name
CefRefPtr<CefV8Value> args = CefV8Value::CreateArray(list->GetSize());
setList(list, args);
callArgs.push_back(args);
CefRefPtr<CefV8Value> retval = func->ExecuteFunction(NULL, callArgs);
if (retval.get()) {
if (retval->IsBool())
handled = retval->GetBoolValue();
}
context->Exit();
}
return handled;
}
我在我的SimplixHandler中调用此函数,但是我通过调用特定的事件函数来调用回调函数,例如:
bool SimplixHandler::notifyDirectoryChanged(std::string directory) {
CefRefPtr<CefListValue> list = CefListValue::Create();
list->SetSize(1);
list->SetString(0, directory);
return executeCallback("onDirectoryChange", list);
}
最后我的Javascript:
function dirChange(dir) {
document.getElementById("filename").innerHTML = "It's something";
}
simplix.setEventCallback("onDirectoryChange", dirChange);
我知道事件被调用(因为我首先因为类的错误链接而导致了nullpointer异常,现在已经修复了),但是Javascript Callback没有被调用。
有谁知道我做错了什么?
提前致谢。
答案 0 :(得分:0)
您可以使用html代码中的任何函数进行回调。
渲染器:
bool SimpleApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message)
{
std::string message_name = message->GetName();
if( message_name == "FUNC")
{
//AfxMessageBox("stop");
//browser->GetMainFrame()->ExecuteJavaScript("super_test('works!');", browser->GetMainFrame()->->GetURL(), 0);
CefRefPtr<CefV8Value> object = m_context->GetGlobal();
CefRefPtr<CefV8Context> v8context = browser->GetMainFrame()->GetV8Context();
v8context->Enter();
CefRefPtr<CefV8Value> func_test = object->GetValue("super_test");
if(func_test == NULL)
{
v8context->Exit();
return false;
}
CefV8ValueList arguments;
CefRefPtr<CefV8Value> test = CefV8Value::CreateString("hello from c++");
arguments.push_back(test);
CefRefPtr<CefV8Value> retval = func_test->ExecuteFunction(NULL, arguments);
v8context->Exit();
return true;
}
return false;
}
jScript:
<script>
function super_test(resp)
{
alert(resp);
return "7777";
}
浏览器:
CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("FUNC");
SimpleHandler::GetInstance()->GetBrowser()->SendProcessMessage(PID_RENDERER, message);