Duilib嵌入CEF以及JavaScript与C++交互

转载:http://blog.csdn.net/foruok/article/details/50573612

转载:http://blog.csdn.net/foruok/article/details/50584985

转载:http://blog.csdn.net/mfcing/article/details/44539035

转载:https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_JavaScript_Cpp.md

转载:https://blog.csdn.net/aseseven/article/details/79482515(CEF3加载本地HTML文件时中文路径乱码的问题解决办法)

转载:https://blog.csdn.net/u012778714/article/category/7003599

JS与Native代码交互,是在Render进程中,所以我们要实现CefRenderProcessHandler接口

一、JS 调用 C++

  • JavaScript注册函数给Render进程,Render进程保存该JavaScript函数
  • Render进程发消息通知Browser进程
  • Browser进程处理后,回发消息给Render进程
  • Render进程调用之前保存的JavaScript函数

1.带参数没有返回值

自己的APP类要继承于CefRenderProcessHandler

 1 #ifndef _CEFBROWSERAPP_H_
 2 #define _CEFBROWSERAPP_H_
 3 #include "include/cef_app.h"
 4 #include "CEFV8HandlerEx.h"
 5 
 6 class CCefBrowserApp
 7     : public CefApp
 8     , public CefBrowserProcessHandler
 9     , public CefRenderProcessHandler
10 {
11 public:
12     CCefBrowserApp();
13 
14     virtual ~CCefBrowserApp();
15 
16 public:
17     virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE { return this; };
18 
19 public:
20     // CefBrowserProcessHandler methods:
21     virtual void OnContextInitialized();
22 
23     //CefRenderProcessHandler methods
24     virtual void OnWebKitInitialized();
25 
26     CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE{ return this; }
27 
28     virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
29 
30     virtual void OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
31 
32 protected:
33 
34     CefRefPtr<CCEFV8HandlerEx> m_v8Handler;
35 
36     IMPLEMENT_REFCOUNTING(CCefBrowserApp);
37 };
38 #endif //_CEFBROWSERAPP_H_

.cpp

 1 #include "CefBrowserApp.h"
 2 #include "stdafx.h"
 3 
 4 
 5 CCefBrowserApp::CCefBrowserApp()
 6     :m_v8Handler(new CCEFV8HandlerEx)
 7 {
 8 }
 9 
10 CCefBrowserApp::~CCefBrowserApp()
11 {
12 }
13 
14 
15 void CCefBrowserApp::OnContextInitialized()
16 {
17     // do nothing here, because we will create browser in my own dialog
18 }
19 
20 void CCefBrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
21                               CefRefPtr<CefFrame> frame,
22                               CefRefPtr<CefV8Context> context)
23 {
24     // Retrieve the context's window object.
25     CefRefPtr<CefV8Value> object = context->GetGlobal();
26 
27     // Create the "NativeLogin" function.
28     CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);
29 
30     // Add the "NativeLogin" function to the "window" object.
31     object->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
32 }
33 
34 void CCefBrowserApp::OnWebKitInitialized()
35 {
36     std::string app_code =
37         "var app;" 
38         "if (!app)"
39         "    app = {};"
40         "(function() {"
41         "    app.GetId = function() {"
42         "        native function GetId();"
43         "        return GetId();"
44         "    };"
45         "})();";
46 
47     // Registered Javascript Function, which will be called by Cpp
48     "  app.registerJavascriptFunction = function(name,callback) {"
49         "    native function registerJavascriptFunction();"
50         "    return registerJavascriptFunction(name,callback);"
51         "  };"
52 
53         "})();";
54 
55 
56     CefRegisterExtension("v8/app", app_code, m_v8Handler);//第一个参数不能为空,否则报错,这个名字可以自定义
57 }

注:CefRegisterExtension的注释
// Example JavaScript extension code:
// <pre>
//   // create the 'example' global object if it doesn't already exist.
//   if (!example)
//     example = {};
//   // create the 'example.test' global object if it doesn't already exist.
//   if (!example.test)
//     example.test = {};
//   (function() {
//     // Define the function 'example.test.myfunction'.
//     example.test.myfunction = function() {
//       // Call CefV8Handler::Execute() with the function name 'MyFunction'
//       // and no arguments.
//       native function MyFunction();
//       return MyFunction();
//     };
//     // Define the getter function for parameter 'example.test.myparam'.
//     example.test.__defineGetter__('myparam', function() {
//       // Call CefV8Handler::Execute() with the function name 'GetMyParam'
//       // and no arguments.
//       native function GetMyParam();
//       return GetMyParam();
//     });
//     // Define the setter function for parameter 'example.test.myparam'.
//     example.test.__defineSetter__('myparam', function(b) {
//       // Call CefV8Handler::Execute() with the function name 'SetMyParam'
//       // and a single argument.
//       native function SetMyParam();
//       if(b) SetMyParam(b);
//     });
//
//     // Extension definitions can also contain normal JavaScript variables
//     // and functions.
//     var myint = 0;
//     example.test.increment = function() {
//       myint += 1;
//       return myint;
//     };
//   })();
// </pre>
// Example usage in the page:
// <pre>
//   // Call the function.
//   example.test.myfunction();
//   // Set the parameter.
//   example.test.myparam = value;
//   // Get the parameter.
//   value = example.test.myparam;
//   // Call another function.
//   example.test.increment();
// </pre>
///
58 
59 void CCefBrowserApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
60 {
61     m_v8Handler = nullptr;
62 }

OnContextCreated给window对象绑定了一个NativeLogin函数,这个函数将由ClientV8Handler类来处理,当HTML中的JS代码调用window.NativeLogin时,ClientV8Handler的Execute方法会被调用。

OnWebKitInitialized注册了一个名为app的JS扩展,在这个扩展里为app定义了GetId方法,app.GetId内部调用了native版本的GetId()。HTML中的JS代码可能如下:

alert(app.GetId());

当浏览器执行上面的代码时,CCEFV8HandlerEx的Execute方法会被调用,现在来看CCEFV8HandlerEx的实现

.h

 1 #ifndef _CEFV8HANDLEREX_H_
 2 #define _CEFV8HANDLEREX_H_
 3 
 4 #include "include/cef_v8.h"
 5 
 6 class CCEFV8HandlerEx : public CefV8Handler {
 7 public:
 8     CCEFV8HandlerEx();
 9 
10     ~CCEFV8HandlerEx();
11 public:
12     virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception) override;
13 private:
14     // Map of message callbacks.
15     typedef std::map<std::pair<std::string, int>, std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value> > >CallbackMap;
16     CallbackMap callback_map_;
17 
18 protected:
19     IMPLEMENT_REFCOUNTING(CCEFV8HandlerEx);
20 };
21 #endif//_CEFV8HANDLEREX_H_

.cpp

 1 #include "CEFV8HandlerEx.h"
 2 #include "stdafx.h"
 3 #include <strsafe.h>
 4 
 5 CCEFV8HandlerEx::CCEFV8HandlerEx()
 6 {
 7 
 8 }
 9 
10 CCEFV8HandlerEx::~CCEFV8HandlerEx()
11 {
12     // Remove any JavaScript callbacks registered for the context that has been released.
13     if (!callback_map_.empty()) {
14         CallbackMap::iterator it = callback_map_.begin();
15         for (; it != callback_map_.end();) {
16             if (it->second.first->IsSame(it->second.first))
17                 callback_map_.erase(it++);
18             else
19                 ++it;
20         }
21     }
22 }
23 
24 
25 bool CCEFV8HandlerEx::Execute(const CefString& name  /*JavaScript调用的C++方法名字*/, CefRefPtr<CefV8Value> object /*JavaScript调用者对象*/, const CefV8ValueList& arguments /*JavaScript传递的参数*/, CefRefPtr<CefV8Value>& retval /*返回给JS的值设置给这个对象*/, CefString& exception/*通知异常信息给JavaScript*/)
26 {
27     if (name == "NativeLogin") 
28     {//Window Binding
29         if (arguments.size() == 2)
30         {
31             CefString strUser = arguments.at(0)->GetStringValue();
32             CefString strPassword = arguments.at(1)->GetStringValue();
33 
34             //TODO: doSomething() in native way
35 
36             CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("login_msg");
37 
38             // Retrieve the argument list object.
39             CefRefPtr<CefListValue> args = msg->GetArgumentList();
40 
41             // Populate the argument values.
42             args->SetSize(2);
43             args->SetString(0, strUser);
44             args->SetString(1, strPassword);
45 
46             // Send the process message to the browser process.
47             CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, msg);
48 
49 
50 
51             retval = CefV8Value::CreateInt(0);//函数的返回值 我们可以拿这个返回值做判断或者其他操作
//var result = window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value);
//document.getElementById("text").innerHTML = result
52         }
53         else
54         {
55             retval = CefV8Value::CreateInt(2);
56         }
57         return true;
58     }
59     else if (name == "GetId") 
60     {//JS Extensions
61         if (arguments.size() == 0) 
62         {
63             // execute javascript 
64             // just for test
65             CefRefPtr<CefFrame> frame = CefV8Context::GetCurrentContext()->GetBrowser()->GetMainFrame();
66             frame->ExecuteJavaScript("alert('Hello, I came from native world.')", frame->GetURL(), 0);
67 
68             // return to JS
69             retval = CefV8Value::CreateString("72395678");
70             return true;
71         }
72     }
73     // Function does not exist.
74     return false;
75 }

在Browser进程中接受Render进程发过来的消息

重写 virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process,CefRefPtr<CefProcessMessage> message);这个虚函数

我把C++函数都写在了窗口类中,所以我对CCefBrowserEventHandler做了修改,把窗口指针传到Browser中,方便调用

.h

 1 #ifndef _CEFBROWSEREVENTHANDLER_H_
 2 #define _CEFBROWSEREVENTHANDLER_H_
 3 #include "include/cef_client.h"  
 4 #include "include/base/cef_lock.h" //线程安全
 5 
 6 
 7 class CMainFrameWnd;
 8 
 9 class CCefBrowserEventHandler
10     : public CefClient
11     , public CefDisplayHandler            // 显示变化事件
12     , public CefLoadHandler                // 加载错误事件
13     , public CefLifeSpanHandler            // 声明周期事件
14     //, public CefContextMenuHandler    // 上下文菜单事件
15     //, public CefDialogHandler            // 对话框事件
16     //, public CefDownloadHandler        // 下载事件
17     //, public CefDragHandler            // 拖拽事件
18     //, public CefFindHandler            // 查找事件
19     //, public ...
20 {
21 public:
22     CCefBrowserEventHandler(CMainFrameWnd* pMainFrame);
23 
24     virtual ~CCefBrowserEventHandler();
25 
26 public:
27     // CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器
28     virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
29     virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
30     virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
31 
32 public:    
33     // display handler method
34     virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE;
35 
36 public:
37     // load handler method
38     virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, 
39         ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE;
40 
41 public:
42     // display handler meethod
43     virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
44     virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
45     virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
46 
47 
48     virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
49         CefProcessId source_process,
50         CefRefPtr<CefProcessMessage> message);
51 
52 
53     bool IsClosing() const { return m_bIsClosing; }
54 
55     CefRefPtr<CefBrowser> GetBrowser(){return m_Browser;} 
56 
57 protected:
58 
59     CefRefPtr<CefBrowser> m_Browser; 
60 
61     bool m_bIsClosing;
62 
63     CMainFrameWnd*      m_pMainWnd;
64 
65     IMPLEMENT_REFCOUNTING(CCefBrowserEventHandler);
66     //由于CEF采用多线程架构,有必要使用锁和闭包来保证在多不同线程安全的传递数据。IMPLEMENT_LOCKING定义提供了Lock()和Unlock()方法以及AutoLock对象来保证不同代码块同步访问
67     IMPLEMENT_LOCKING(CCefBrowserEventHandler);//必须包含#include "include/base/cef_lock.h" 
68 };
69 
70 #endif//_CEFBROWSEREVENTHANDLER_H_

.cpp

  1 #include "CefBrowserEventHandler.h"
  2 #include "stdafx.h"
  3 #include <sstream>
  4 #include <string>
  5 #include "include/cef_app.h"
  6 #include "include/wrapper/cef_closure_task.h"
  7 #include "include/wrapper/cef_helpers.h"
  8 #include "MainFrameWnd.h"
  9 
 10 
 11 CCefBrowserEventHandler::CCefBrowserEventHandler(CMainFrameWnd* pMainFrame)
 12     :m_bIsClosing(false)
 13     ,m_pMainWnd(pMainFrame)
 14 {
 15 
 16 }
 17 
 18 CCefBrowserEventHandler::~CCefBrowserEventHandler()
 19 {
 20 
 21 }
 22 
 23 CefRefPtr<CefDisplayHandler> CCefBrowserEventHandler::GetDisplayHandler()
 24 {
 25     return this;
 26 }
 27 
 28 CefRefPtr<CefLifeSpanHandler> CCefBrowserEventHandler::GetLifeSpanHandler()
 29 {
 30     return this;
 31 }
 32 
 33 CefRefPtr<CefLoadHandler> CCefBrowserEventHandler::GetLoadHandler() 
 34 {
 35     return this;
 36 }
 37 
 38 void CCefBrowserEventHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) 
 39 {
 40     
 41 }
 42 
 43 void CCefBrowserEventHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, 
 44                                           const CefString& errorText, const CefString& failedUrl) 
 45 {
 46     CEF_REQUIRE_UI_THREAD();
 47     if (ERR_ABORTED == errorCode)
 48         return ;
 49 
 50     std::stringstream ss;
 51     ss <<    "<html><body bgcolor=\"white\">"
 52             "<h2>Failed to load URL " << std::string(failedUrl) <<
 53             " with error " << std::string(errorText) << " (" << errorCode <<
 54             ").</h2></body></html>";
 55     frame->LoadString(ss.str(), failedUrl);
 56 }
 57 
 58 void CCefBrowserEventHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) 
 59 {
 60     CEF_REQUIRE_UI_THREAD();
 61 
 62     //base::AutoLock lock_scope(lock_);
 63 
 64     AutoLock lock_scope(this);
 65 
 66      m_Browser = browser;
 67 
 68 }
 69 
 70 bool CCefBrowserEventHandler::DoClose(CefRefPtr<CefBrowser> browser)
 71 {
 72     CEF_REQUIRE_UI_THREAD();
 73 
 74     //base::AutoLock lock_scope(lock_);
 75     AutoLock lock_scope(this);
 76 
 77 
 78     if(m_Browser) 
 79     {
 80         // Set a flag to indicate that the window close should be allowed.
 81         m_bIsClosing = true;
 82     }
 83 
 84     return false;
 85 }
 86 
 87 void CCefBrowserEventHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) 
 88 {
 89     CEF_REQUIRE_UI_THREAD();
 90 
 91     //base::AutoLock lock_scope(lock_);
 92     AutoLock lock_scope(this);
 93 
 94     if(m_Browser->IsSame(browser))  
 95         m_Browser = NULL;
 96 }
 97 
 98 bool CCefBrowserEventHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
 99                                       CefProcessId source_process,
100                                       CefRefPtr<CefProcessMessage> message) 
101 {
102     const std::string& messageName = message->GetName();
103     if (messageName == "login_msg") 
104     {   
105         // extract message
106         CefRefPtr<CefListValue> args = message->GetArgumentList();
107         CefString strUser = args->GetString(0);
108         CefString strPassword = args->GetString(1);
109 
110         m_pMainWnd->CEFLoginJsCallCPP(strUser,strPassword);//窗口类的成员函数
111 
112                 //如果函数有返回值也可以通过向Render发送消息传递
113         //send reply to render process
114         CefRefPtr<CefProcessMessage> outMsg = CefProcessMessage::Create("login_reply");
115 
116         // Retrieve the argument list object.
117         CefRefPtr<CefListValue> replyArgs = outMsg->GetArgumentList();
118 
119         // Populate the argument values.
120         replyArgs->SetSize(1);
121         replyArgs->SetInt(0, 0);
122 
123         // Send the process message to the renderer process.
124         browser->SendProcessMessage(PID_RENDERER, outMsg);
125 
126         return true;
127     }
128 
129     return false;
130 }

Browser进程处理完后向Render进程发了消息,The render process receives the IPC message处理

.h

 1 #ifndef _CEFBROWSERAPP_H_
 2 #define _CEFBROWSERAPP_H_
 3 #include "include/cef_app.h"
 4 #include "CEFV8HandlerEx.h"
 5 
 6 class CCefBrowserApp
 7     : public CefApp
 8     , public CefBrowserProcessHandler
 9     , public CefRenderProcessHandler
10 {
11 public:
12     CCefBrowserApp();
13 
14     virtual ~CCefBrowserApp();
15 
16 public:
17     virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE { return this; };
18 
19 public:
20     // CefBrowserProcessHandler methods:
21     virtual void OnContextInitialized();
22 
23     //CefRenderProcessHandler methods
24     virtual void OnWebKitInitialized();
25 
26     CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE{ return this; }
27 
28     virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
29 
30     virtual void OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
31 
32     //收消息
33     virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message);
34 
35 protected:
36 
37     CefRefPtr<CCEFV8HandlerEx> m_v8Handler;
38 
39     IMPLEMENT_REFCOUNTING(CCefBrowserApp);
40 };
41 #endif //_CEFBROWSERAPP_H_

.cpp

 1 #include "CefBrowserApp.h"
 2 #include "stdafx.h"
 3 
 4 
 5 CCefBrowserApp::CCefBrowserApp()
 6     :m_v8Handler(new CCEFV8HandlerEx)
 7 {
 8 }
 9 
10 CCefBrowserApp::~CCefBrowserApp()
11 {
12 }
13 
14 
15 void CCefBrowserApp::OnContextInitialized()
16 {
17     // do nothing here, because we will create browser in my own dialog
18 }
19 
20 void CCefBrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
21                               CefRefPtr<CefFrame> frame,
22                               CefRefPtr<CefV8Context> context)
23 {
24     // Retrieve the context's window object.
25     CefRefPtr<CefV8Value> object = context->GetGlobal();
26 
27     // Create the "NativeLogin" function.
28     CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);//第一个参数和SetValue参数保持一致,否则无法调用
29 
30     // Add the "NativeLogin" function to the "window" object.
31     object->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
32 
33     // Add the "register" function to the "window" object.
34     object->SetValue("register",CefV8Value::CreateFunction("register", m_v8Handler),V8_PROPERTY_ATTRIBUTE_NONE);
35 }
36 
37 void CCefBrowserApp::OnWebKitInitialized()
38 {
39     std::string app_code =
40         "var app;"
41         "if (!app)"
42         "    app = {};"
43         "(function() {"
44         "    app.GetId = function() {"
45         "        native function GetId();"
46         "        return GetId();"
47         "    };"
48         "})();";
49 
50     // Registered Javascript Function, which will be called by Cpp
51     "  app.registerJavascriptFunction = function(name,callback) {"
52         "    native function registerJavascriptFunction();"
53         "    return registerJavascriptFunction(name,callback);"
54         "  };"
55 
56         "})();";
57 
58 
59     CefRegisterExtension("v8/app", app_code, m_v8Handler);//第一个参数不能为空
60 }
61 
62 void CCefBrowserApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
63 {
64     m_v8Handler = nullptr;
65 }
66 
67 bool CCefBrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefProcessId source_process,CefRefPtr<CefProcessMessage> message) 
68 {
69     const std::string& messageName = message->GetName();
70     if (messageName == "login_reply")
71     {
72         // extract message
73         CefRefPtr<CefListValue> args = message->GetArgumentList();
74         bool status = args->GetBool(0);
75 
76         CefRefPtr<CefFrame> frame = browser->GetMainFrame();
77 
78         if (status)
79         {
80             frame->ExecuteJavaScript("IsSuccess();", frame->GetURL(), 0);
81         }
82         
83         return true;
84     }
85 
86     return false;
87 }

 

2.JS CallBack 

 在OnContextCreated()函数中给window绑定函数

1 // Create the "register" function.
2     CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("register", m_v8Handler);//第一个参数和SetValue参数保持一致,否则无法调用
3 
4 // Add the "register" function to the "window" object.
5     object->SetValue("register", func, V8_PROPERTY_ATTRIBUTE_NONE);

在Exectue()函数中处理

else if (name == "register")
{if (arguments.size() == 1 && arguments[0]->IsFunction()) {CefRefPtr<CefV8Value> callback_func_ = arguments[0];CefRefPtr<CefV8Context> callback_context_ = CefV8Context::GetCurrentContext();callback_func_->ExecuteFunction(NULL, arguments);//执行回调函数return true;}
}

在HTML的JavaScript里这样写

  function myFunc() 
{// do something in JS.alert("callback");
}//js CALLback
function CallBack()
{window.register(myFunc);
}

 3.C++ 调用 JS

C++调用JS函数相对简单多了,因为CEF有接口可以直接使用CefFrame::ExecuteJavaScript,看看注释:

 1  ///
 2   // Execute a string of JavaScript code in this frame. The |script_url|
 3   // parameter is the URL where the script in question can be found, if any.
 4   // The renderer may request this URL to show the developer the source of the
 5   // error.  The |start_line| parameter is the base line number to use for error
 6   // reporting.
 7   ///
 8   /*--cef(optional_param=script_url)--*/
 9   virtual void ExecuteJavaScript(const CefString& code,
10                                  const CefString& script_url,
11                                  int start_line) =0;

首先需要获取到我们的浏览器里的主框架对象,code是JS函数和传入参数的字符串,URL可以直接忽略。

1 CefRefPtr<CefFrame> frame = m_handler->GetBrowser()->GetMainFrame();
2 
3 m_handler是我们自己定义的Handler对象
4 
5 /C++ 调用js方法
6 //frame->ExecuteJavaScript(L"Test();",frame->GetURL(),0);//提示框
7 //frame->ExecuteJavaScript(L"ModifyValue();",frame->GetURL(),0);//无参数函数
8 frame->ExecuteJavaScript(L"ModifyValue('巴萨牛逼');",frame->GetURL(),0);//有参数函数
9 如果参数是可变的,可以这样
CString strJsCode;
strJsCode.Format(L"setInstallStatus('%s','%s','%d');", lpData->strId.c_str(), strStatus, nPercent);
其中setInstallStatus是js函数,它有三个参数

我在HMTL里写的

  function Test()
{alert("js被C++非礼了");
}function ModifyValue( arr)
{//document.getElementById("text").innerHTML = "被修改了";alert(arr);document.getElementById("text").innerHTML = arr;}

 

转载于:https://www.cnblogs.com/chechen/p/6138167.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

layui分页limit不显示_【图片】新手 分页显示不了呀【layui吧】_百度贴吧

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼$(function () {layui.use([table, layer], function () {layer layui.layer, layuiTable layui.table;tabSalesList layuiTable.render({elem: "#JFTZTJ",totalRow: true,url: /DailyRoutine/MembershipManagement/O…

netbeans代码提示_NetBeans可用性提示

netbeans代码提示的Java IDE都来了&#xff0c;因为在很长的路要走天的JBuilder的 &#xff08;尽管JBuilder中似乎是一个值得欢迎提前在时间&#xff09;。 当今的Java IDE&#xff08;例如NetBeans &#xff0c; Eclipse &#xff0c; IntelliJ IDEA和JDeveloper &#xff09…

推荐文章:机器学习:“一文读懂机器学习,大数据/自然语言处理/算法全有了...

PS:文章主要转载自CSDN大神"黑夜路人"的文章: http://blog.csdn.NET/heiyeshuwu/article/details/43483655 本文主要对机器学习进行科普,包括机器学习的定义、范围、方法,包括机器学习的研究领域&#xff1a;模式识别、计算机视觉、语音识别、自然语言…

java比较炫的登录界面_html+css实现漂亮的透明登录页面,HTML实现炫酷登录页面...

承蒙各位小伙伴的支持&#xff0c;鄙人有幸入围了《CSDN 2020博客之星》的前200名&#xff0c;现在进入投票环节&#xff0c;如果我平时写的文章和分享对你有用的话&#xff0c;请每天点击一下这个链接&#xff0c;投上你们宝贵的一票吧&#xff01;谢谢&#xff01;❤️ 每一票…

在OpenShift上扩展Java EE微服务

这个小系列的前两个部分介绍了如何使用WildFly Swarm构建一个微型JAX-RS服务并将其打包到Docker映像中 。 您学习了如何将此示例部署到OpenShift &#xff0c;现在该进行一点扩展了。 为什么扩展很重要 基于微服务的体系结构的关键方面之一是分解为高性能的单个服务&#xff0…

mssql 远程无法连接mysql_在本地 怎么远程连接MSSQL数据库

hp连接mssql数据库有几个注意事项&#xff0c;尤其mssql的多个版本、32位、64位都有区别。首先&#xff0c;php.ini文件中;extensionphp_pdo_mssql.dll ;extensionphp_pdo_odbc.dll 前面的分号去掉&#xff0c;对应的使哪种方式连接mssql。注意要重启服务使其生效。一、建立连接…

jQuery 一些小技巧

1. 返回顶部按钮 可以利用 animate 和 scrollTop 来实现返回顶部的动画&#xff0c;而不需要使用其他插件。 // Back to top $(a.ktop).click(function () { $(document.body).animate({scrollTop: 0}, 800);…

OpenMap教程第2部分–使用MapHandler构建基本地图应用程序–第1部分

1.简介 在第一个教程中&#xff0c;我们创建了一个基本的OpenMap GIS应用程序&#xff0c;该应用程序在JFrame中显示一个从文件系统加载的具有一个形状图层的地图。 该教程基于com.bbn.openmap.app.example.SimpleMap 。 在该教程中&#xff0c;我们使用了以下OpenMap类&#x…

JS实战 · 复选框全选操作

思路&#xff1a;1、获取被选中checkbox&#xff0c;通过checked属性的状态完成&#xff1b;2、获取被选中的checkbox的value值&#xff1b;3、求所有value的和sum&#xff1b;4、定义span区域存储和sum&#xff1b;代码如下&#xff1a;<html><head><meta http…

java二叉树删除子树_132-BST删除有一颗子树的结点

2.网上数据结构和算法的课程不少&#xff0c;但存在两个问题&#xff1a;1)授课方式单一&#xff0c;大多是照着代码念一遍&#xff0c;数据结构和算法本身就比较难理解&#xff0c;对基础好的学员来说&#xff0c;还好一点&#xff0c;对基础不好的学生来说&#xff0c;基本上…

使用djcproxy创建代理对象

在过去的几周中&#xff0c;我展示了如何使用Java Reflection API和cglib创建代理对象。 在本文中&#xff0c;我将向您展示如何使用djcproxy做到这一点。 哦&#xff0c;不是&#xff0c;另一个代理实现&#xff01; 除了我创建此代理的自私事实之外&#xff0c;还要写些什么…

lightoj1145 【DP优化求方案】

题意&#xff1a; 有一个k面的骰子&#xff0c;然后问你n个骰子朝上的面数字之和s的方案&#xff1b;思路&#xff1a;dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案&#xff1b;显然dp[i][j] dp[i - 1][j - 1] dp[i - 1][j - 2] ... dp[i - 1][j - k];我们算 dp[i][j] 的…

java rx.observable_Rxjava2 Observable的条件操作符详解及实例

简要&#xff1a;需求了解&#xff1a;在使用 Rxjava 开发中&#xff0c;经常有一些各种条件的操作 &#xff0c;如比较两个 Observable 谁先发射了数据、跳过指定条件的 Observable 等一系列的条件操作需求&#xff0c;那么很幸运&#xff0c; Rxjava 中已经有了很多条件操作符…

Linux poll 和 select 机制

poll select 介绍 使用非阻塞 I/O 的应用程序常常使用 poll, select, 和 epoll 系统调用. poll, select 和 epoll 本质上有相同的功能: 每个允许一个进程来决定它是否可读或者写一个 或多个文件而不阻塞. 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来 读或写.…

hprof 不大 泄露_HPROF –内存泄漏分析教程

hprof 不大 泄露本文将为您提供有关如何通过生成和分析Sun HotSpot JVM HPROF堆转储文件来分析JVM内存泄漏问题的教程。 一个现实的案例研究将用于此目的&#xff1a;Weblogic 9.2内存泄漏影响Weblogic Admin服务器。 环境规格 Java EE服务器&#xff1a;Oracle Weblogic Ser…

java枚举怎么编译不行的_java枚举类型

public classTestEnum {/*最普通的枚举*/public enumColorSelect {red, green, yellow, blue;}/*枚举也可以象一般的类一样添加方法和属性,你可以为它添加静态和非静态的属性或方法,这一切都象你在一般的类中做的那样.*/public enumSeason {//枚举列表必须写在最前面&#xff0…

eclipse光标变成黑块变粗解决办法

就是按下了键盘的insert按键转载于:https://www.cnblogs.com/panxuejun/p/6170717.html

投资银行对Java进行的二十大核心面试问答

这是在金融领域&#xff08;主要是大型投资银行&#xff09;共享Java核心访谈问题和答案的新系列。 在JP Morgan&#xff0c;Morgan Stanley&#xff0c;Barclays或Goldman Sachs上会问许多这些Java面试问题。 银行主要从多线程 &#xff0c; 集合 &#xff0c;序列化&#xff…

java 支付重复问题_Airbnb支付系统如何在分布式环境下避免重复打款

原文链接&#xff1a;https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bbAirbnb一直在将其基础架构迁移到面向服务的体系结构(SOA)。 SOA具有许多优势&#xff0c;例如使开发人员能够专业化并具有更快迭代的能力。…

用注解方式写定时任务

spring里加上 </context:component-scan><!-- 任务自动扫描 --><task:annotation-driven/><!-- 扫描位置 --><context:annotation-config/> <context:component-scan base-package"com.xxx.xxx"/>然后在类上面添加注解 Compon…