转载: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. CCefBrowserApp::CCefBrowserApp()
  5. :m_v8Handler(new CCEFV8HandlerEx)
  6. {
  7. }
  8.  
  9. CCefBrowserApp::~CCefBrowserApp()
  10. {
  11. }
  12.  
  13. void CCefBrowserApp::OnContextInitialized()
  14. {
  15. // do nothing here, because we will create browser in my own dialog
  16. }
  17.  
  18. void CCefBrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
  19. CefRefPtr<CefFrame> frame,
  20. CefRefPtr<CefV8Context> context)
  21. {
  22. // Retrieve the context's window object.
  23. CefRefPtr<CefV8Value> object = context->GetGlobal();
  24.  
  25. // Create the "NativeLogin" function.
  26. CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);
  27.  
  28. // Add the "NativeLogin" function to the "window" object.
  29. object->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
  30. }
  31.  
  32. void CCefBrowserApp::OnWebKitInitialized()
  33. {
  34. std::string app_code =
  35. "var app;"
  36. "if (!app)"
  37. " app = {};"
  38. "(function() {"
  39. " app.GetId = function() {"
  40. " native function GetId();"
  41. " return GetId();"
  42. " };"
  43. "})();";
  44.  
  45. // Registered Javascript Function, which will be called by Cpp
  46. " app.registerJavascriptFunction = function(name,callback) {"
  47. " native function registerJavascriptFunction();"
  48. " return registerJavascriptFunction(name,callback);"
  49. " };"
  50.  
  51. "})();";
  52.  
  53. CefRegisterExtension("v8/app", app_code, m_v8Handler);//第一个参数不能为空,否则报错,这个名字可以自定义
  54. }
  55.  
  56. 注:CefRegisterExtension的注释
  1. // Example JavaScript extension code:
  2. // <pre>
  3. // // create the 'example' global object if it doesn't already exist.
  4. // if (!example)
  5. // example = {};
  6. // // create the 'example.test' global object if it doesn't already exist.
  7. // if (!example.test)
  8. // example.test = {};
  9. // (function() {
  10. // // Define the function 'example.test.myfunction'.
  11. // example.test.myfunction = function() {
  12. // // Call CefV8Handler::Execute() with the function name 'MyFunction'
  13. // // and no arguments.
  14. // native function MyFunction();
  15. // return MyFunction();
  16. // };
  17. // // Define the getter function for parameter 'example.test.myparam'.
  18. // example.test.__defineGetter__('myparam', function() {
  19. // // Call CefV8Handler::Execute() with the function name 'GetMyParam'
  20. // // and no arguments.
  21. // native function GetMyParam();
  22. // return GetMyParam();
  23. // });
  24. // // Define the setter function for parameter 'example.test.myparam'.
  25. // example.test.__defineSetter__('myparam', function(b) {
  26. // // Call CefV8Handler::Execute() with the function name 'SetMyParam'
  27. // // and a single argument.
  28. // native function SetMyParam();
  29. // if(b) SetMyParam(b);
  30. // });
  31. //
  32. // // Extension definitions can also contain normal JavaScript variables
  33. // // and functions.
  34. // var myint = 0;
  35. // example.test.increment = function() {
  36. // myint += 1;
  37. // return myint;
  38. // };
  39. // })();
  40. // </pre>
  41. // Example usage in the page:
  42. // <pre>
  43. // // Call the function.
  44. // example.test.myfunction();
  45. // // Set the parameter.
  46. // example.test.myparam = value;
  47. // // Get the parameter.
  48. // value = example.test.myparam;
  49. // // Call another function.
  50. // example.test.increment();
  51. // </pre>
  52. ///
  1. void CCefBrowserApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
  2. {
  3. m_v8Handler = nullptr;
  4. }

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

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

  1. 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. bool CCEFV8HandlerEx::Execute(const CefString& name /*JavaScript调用的C++方法名字*/, CefRefPtr<CefV8Value> object /*JavaScript调用者对象*/, const CefV8ValueList& arguments /*JavaScript传递的参数*/, CefRefPtr<CefV8Value>& retval /*返回给JS的值设置给这个对象*/, CefString& exception/*通知异常信息给JavaScript*/)
  25. {
  26. if (name == "NativeLogin")
  27. {//Window Binding
  28. if (arguments.size() == )
  29. {
  30. CefString strUser = arguments.at()->GetStringValue();
  31. CefString strPassword = arguments.at()->GetStringValue();
  32.  
  33. //TODO: doSomething() in native way
  34.  
  35. CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("login_msg");
  36.  
  37. // Retrieve the argument list object.
  38. CefRefPtr<CefListValue> args = msg->GetArgumentList();
  39.  
  40. // Populate the argument values.
  41. args->SetSize();
  42. args->SetString(, strUser);
  43. args->SetString(, strPassword);
  44.  
  45. // Send the process message to the browser process.
  46. CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, msg);
  47.  
  48. retval = CefV8Value::CreateInt();//函数的返回值 我们可以拿这个返回值做判断或者其他操作
    //var result = window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value);
    //document.getElementById("text").innerHTML = result
  1. }
  2. else
  3. {
  4. retval = CefV8Value::CreateInt();
  5. }
  6. return true;
  7. }
  8. else if (name == "GetId")
  9. {//JS Extensions
  10. if (arguments.size() == )
  11. {
  12. // execute javascript
  13. // just for test
  14. CefRefPtr<CefFrame> frame = CefV8Context::GetCurrentContext()->GetBrowser()->GetMainFrame();
  15. frame->ExecuteJavaScript("alert('Hello, I came from native world.')", frame->GetURL(), );
  16. // return to JS
  17. retval = CefV8Value::CreateString("");
  18. return true;
  19. }
  20. }
  21. // Function does not exist.
  22. return false;
  23. }

在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. class CMainFrameWnd;
  7.  
  8. class CCefBrowserEventHandler
  9. : public CefClient
  10. , public CefDisplayHandler // 显示变化事件
  11. , public CefLoadHandler // 加载错误事件
  12. , public CefLifeSpanHandler // 声明周期事件
  13. //, public CefContextMenuHandler // 上下文菜单事件
  14. //, public CefDialogHandler // 对话框事件
  15. //, public CefDownloadHandler // 下载事件
  16. //, public CefDragHandler // 拖拽事件
  17. //, public CefFindHandler // 查找事件
  18. //, public ...
  19. {
  20. public:
  21. CCefBrowserEventHandler(CMainFrameWnd* pMainFrame);
  22.  
  23. virtual ~CCefBrowserEventHandler();
  24.  
  25. public:
  26. // CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器
  27. virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
  28. virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
  29. virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
  30.  
  31. public:
  32. // display handler method
  33. virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE;
  34.  
  35. public:
  36. // load handler method
  37. virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
  38. ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE;
  39.  
  40. public:
  41. // display handler meethod
  42. virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
  43. virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
  44. virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
  45.  
  46. virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
  47. CefProcessId source_process,
  48. CefRefPtr<CefProcessMessage> message);
  49.  
  50. bool IsClosing() const { return m_bIsClosing; }
  51.  
  52. CefRefPtr<CefBrowser> GetBrowser(){return m_Browser;}
  53.  
  54. protected:
  55.  
  56. CefRefPtr<CefBrowser> m_Browser;
  57.  
  58. bool m_bIsClosing;
  59.  
  60. CMainFrameWnd* m_pMainWnd;
  61.  
  62. IMPLEMENT_REFCOUNTING(CCefBrowserEventHandler);
  63. //由于CEF采用多线程架构,有必要使用锁和闭包来保证在多不同线程安全的传递数据。IMPLEMENT_LOCKING定义提供了Lock()和Unlock()方法以及AutoLock对象来保证不同代码块同步访问
  64. IMPLEMENT_LOCKING(CCefBrowserEventHandler);//必须包含#include "include/base/cef_lock.h"
  65. };
  66.  
  67. #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. CCefBrowserEventHandler::CCefBrowserEventHandler(CMainFrameWnd* pMainFrame)
  11. :m_bIsClosing(false)
  12. ,m_pMainWnd(pMainFrame)
  13. {
  14.  
  15. }
  16.  
  17. CCefBrowserEventHandler::~CCefBrowserEventHandler()
  18. {
  19.  
  20. }
  21.  
  22. CefRefPtr<CefDisplayHandler> CCefBrowserEventHandler::GetDisplayHandler()
  23. {
  24. return this;
  25. }
  26.  
  27. CefRefPtr<CefLifeSpanHandler> CCefBrowserEventHandler::GetLifeSpanHandler()
  28. {
  29. return this;
  30. }
  31.  
  32. CefRefPtr<CefLoadHandler> CCefBrowserEventHandler::GetLoadHandler()
  33. {
  34. return this;
  35. }
  36.  
  37. void CCefBrowserEventHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
  38. {
  39.  
  40. }
  41.  
  42. void CCefBrowserEventHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode,
  43. const CefString& errorText, const CefString& failedUrl)
  44. {
  45. CEF_REQUIRE_UI_THREAD();
  46. if (ERR_ABORTED == errorCode)
  47. return ;
  48.  
  49. std::stringstream ss;
  50. ss << "<html><body bgcolor=\"white\">"
  51. "<h2>Failed to load URL " << std::string(failedUrl) <<
  52. " with error " << std::string(errorText) << " (" << errorCode <<
  53. ").</h2></body></html>";
  54. frame->LoadString(ss.str(), failedUrl);
  55. }
  56.  
  57. void CCefBrowserEventHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
  58. {
  59. CEF_REQUIRE_UI_THREAD();
  60.  
  61. //base::AutoLock lock_scope(lock_);
  62.  
  63. AutoLock lock_scope(this);
  64.  
  65. m_Browser = browser;
  66.  
  67. }
  68.  
  69. bool CCefBrowserEventHandler::DoClose(CefRefPtr<CefBrowser> browser)
  70. {
  71. CEF_REQUIRE_UI_THREAD();
  72.  
  73. //base::AutoLock lock_scope(lock_);
  74. AutoLock lock_scope(this);
  75.  
  76. if(m_Browser)
  77. {
  78. // Set a flag to indicate that the window close should be allowed.
  79. m_bIsClosing = true;
  80. }
  81.  
  82. return false;
  83. }
  84.  
  85. void CCefBrowserEventHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
  86. {
  87. CEF_REQUIRE_UI_THREAD();
  88.  
  89. //base::AutoLock lock_scope(lock_);
  90. AutoLock lock_scope(this);
  91.  
  92. if(m_Browser->IsSame(browser))
  93. m_Browser = NULL;
  94. }
  95.  
  96. bool CCefBrowserEventHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
  97. CefProcessId source_process,
  98. CefRefPtr<CefProcessMessage> message)
  99. {
  100. const std::string& messageName = message->GetName();
  101. if (messageName == "login_msg")
  102. {
  103. // extract message
  104. CefRefPtr<CefListValue> args = message->GetArgumentList();
  105. CefString strUser = args->GetString();
  106. CefString strPassword = args->GetString();
  107.  
  108. m_pMainWnd->CEFLoginJsCallCPP(strUser,strPassword);//窗口类的成员函数
  109.  
  110. //如果函数有返回值也可以通过向Render发送消息传递
  111. //send reply to render process
  112. CefRefPtr<CefProcessMessage> outMsg = CefProcessMessage::Create("login_reply");
  113.  
  114. // Retrieve the argument list object.
  115. CefRefPtr<CefListValue> replyArgs = outMsg->GetArgumentList();
  116.  
  117. // Populate the argument values.
  118. replyArgs->SetSize();
  119. replyArgs->SetInt(, );
  120.  
  121. // Send the process message to the renderer process.
  122. browser->SendProcessMessage(PID_RENDERER, outMsg);
  123.  
  124. return true;
  125. }
  126.  
  127. return false;
  128. }

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

 

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()函数中处理

  1. else if (name == "register")
  2. {
  3. if (arguments.size() == && arguments[]->IsFunction())
  4. {
  5. CefRefPtr<CefV8Value> callback_func_ = arguments[];
  6. CefRefPtr<CefV8Context> callback_context_ = CefV8Context::GetCurrentContext();
  7.  
  8. callback_func_->ExecuteFunction(NULL, arguments);//执行回调函数
  9.  
  10. return true;
  11. }
  12. }

在HTML的JavaScript里这样写

  1. function myFunc()
  2. {
  3. // do something in JS.
  4. alert("callback");
  5. }
  6.  
  7. //js CALLback
  8. function CallBack()
  9. {
  10. window.register(myFunc);
  11. }

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) =;

首先需要获取到我们的浏览器里的主框架对象,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(),);//有参数函数
    9 如果参数是可变的,可以这样
  1. CString strJsCode;
    strJsCode.Format(L"setInstallStatus('%s','%s','%d');", lpData->strId.c_str(), strStatus, nPercent);
  1. 其中setInstallStatusjs函数,它有三个参数

我在HMTL里写的

  1. function Test()
  2. {
  3. alert("js被C++非礼了");
  4. }
  5.  
  6. function ModifyValue( arr)
  7. {
  8. //document.getElementById("text").innerHTML = "被修改了";
  9.  
  10. alert(arr);
  11. document.getElementById("text").innerHTML = arr;
  12. }

Duilib嵌入CEF以及JavaScript与C++交互的更多相关文章

  1. CEF中JavaScript与C++交互

    在CEF里,JS和Native(C/C++)代码能够非常方便的交互,这里https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegr ...

  2. Duilib嵌入CEF出现窗口显示不正常

    参考资料:https://www.aliyun.com/zixun/wenji/1247250.html 转载:https://www.cnblogs.com/gongxijun/p/4857977. ...

  3. Duilib嵌入CEF禁止浏览器响应拖拽事件

    转载:http://blog.csdn.net/liuyan20092009/article/details/53819473 转载:https://blog.csdn.net/u012778714( ...

  4. iOS中JavaScript和OC交互

    转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...

  5. jQuery基础与JavaScript与CSS交互-第五章

    目录 JavaScript框架种类及其优缺点 jQuery库 jQuery对象$ 掌握基本选择器 掌握过滤选择器 掌握表单选择器 RIA技术 常见的RIA技术 Ajax Sliverlight Fle ...

  6. 在android中实现webview与javascript之间的交互(转)

    参见“在android中实现webview与javascript之间的交互”

  7. Hybrid App: 对比UIWebView和WebKit实现JavaScript与Native交互

    一.简介 在前面一篇文章中讲到过实现JavaScript与Native交互的方式有一种就是使用原生内嵌webView.在iOS8之前,开发者只能使用苹果提供的UIWebView类来加载URL或者HTM ...

  8. Qt和JavaScript使用QWebChannel交互一——和Qt内嵌网页交互

    Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 目录 Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 前言 一.效果 二.实现过程 ...

  9. iOS中JavaScript和OC交互 --by 胡 xu

    在iOS开发中很多时候我们会和UIWebView打交道,目前国内的很多应用都采用了UIWebView的混合编程技术,最常见的是微信公众号的内容页面.前段时间在做微信公众平台相关的开发,发现很多应用场景 ...

随机推荐

  1. 升级win8.1后mysql服务不能启动的问题

    升级win8.1后发现服务列表中MySQL55不见了. 1. 先把服务恢复. mysql没有看到maitenance,找到安装文件 mysql-installer-community-5.6.12.0 ...

  2. Net中httpResponse和httpRequest的简单实用;

    这对象很简单,封装很多常用的方法和属性:使用起来也很方便: 这个关键是要对我们的 http中的各种协议要很了解滴呀: 模拟一个简单的暴力破解: public static class HttpInfo ...

  3. 英康手机订单系统APP使用说明

    1.登陆手机APP 输入卖家提供的账号和密码登陆APP. 2.商品购买列表 可以在全部商品.促销商品.收藏商品.最近订购.再次购买等几种商品列表下把商品加入购物车: 3.加入商品到购物车 点击商品列表 ...

  4. ios - runtime运行时应用---交换方法

    runtime运行时用法之一 --- 交换类的方法,此处简单写了把系统的UIView的setBackgroundColor的方法换成了自定义的pb_setBackgroundColor 首先创建UIV ...

  5. onload事件-----addLoadEvent函数

    在给网页加一些特效时经常要在<body>中加入“onload”事件,即在网页加载完后执行某事件,例如:<body onload=”alert(‘欢迎光临!')”,但这样做有个大的缺陷 ...

  6. PC管理端与评委云打分配合步骤及疑难问题汇编,即如何使用PC管理端的云服务管理功能

    一.前期环境及数据准备 A.PC管理端主要流程 1.进入菜单 编辑/选项/服务器 界面,如下图所示,采用我官方所提供的云服务,不采用自己假设的AppWeb服务. 切记:AppWeb服务和云服务只能二选 ...

  7. html页面定位

    对于css中的position:relative;我始终搞不明白它是什么意思,有什么作用? 对于position的其它几个属性,我都搞懂了 引用 static : 无特殊定位,对象遵循HTML定位规则 ...

  8. 暑假CTF训练一

    暑假CTF训练一 围在栅栏中的爱 题目: 最近一直在好奇一个问题,QWE到底等不等于ABC? -.- .. --.- .-.. .-- - ..-. -.-. --.- --. -. ... --- ...

  9. AD中各层的说明

    PCB各层说明: 1.丝印层(OverLay,Silkscreen):有顶层丝印和底层丝印.用来画器件轮廓,器件编号和一些图案等. 2.信号层(SignalLayer):对于两层板,主要是TopLay ...

  10. NOI 1.5 42:画矩形

    描述 根据参数,画出矩形. 输入 输入一行,包括四个参数:前两个参数为整数,依次代表矩形的高和宽(高不少于3行不多于10行,宽不少于5列不多于10列):第三个参数是一个字符,表示用来画图的矩形符号:第 ...