3.1     CEF和JavaScript交互

3.1.1     在CEF执行JavaScript脚本

3.1.2     窗口绑定方式实现CEF设置JavaScript的变量

3.1.3     扩展方式(Extension)实现CEF设置JavaScript的变量

3.1.4     窗口绑定方式实现CEF给JavaScript提供函数

3.1.5     Extension方式实现CEF给JavaScript提供函数

3.1  CEF和JavaScript交互

https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration.md

CEF使用的V8 JavaScript 引擎用于内部JavaScript实现,每一个frame都有JS上下文(context),为JS代码执行提供范围和安全。CEF暴露了很多JS特性可以和客户端程序进行交互。

3.1.1         在CEF执行JavaScript脚本

应用场景是需要在CEF中拦截一个URL请求,并把它重定向到另外一个URL,可以调用pFrame->ExecuteJavaScript来执行一个JavaScript脚本,实现跳转。当然也可以实现其他应用功能。

CefRefPtr<CefFrame> pFrame = browser->GetMainFrame();

std::string strurl = pFrame->GetURL().ToString();

std::string strname = pFrame->GetName().ToString();

pFrame->GetName().ToString().c_str());

if (pFrame->GetURL() == "https://10.19.141.75/portal/")

{

pFrame->ExecuteJavaScript("var param= { url:'https://10.19.141.75/ishelf-web/personalCenter' }; \

window.goToApp(param);\

var paramEx = { isExtend:true };\

window.extendScreen(paramEx);\

", pFrame->GetURL(), 0);

}

3.1.2         窗口绑定方式实现CEF设置JavaScript的变量

在CEF程序中,创建一个CefV8Value对象,获取上下文的窗口对象,注入窗口对象一个变量值,网页中就可以使用JavaScript获取这个变量值。窗口绑定在CefRenderProcessHandler::OnContextCreated()函数中。是上下文创建响应函数,窗口绑定方式在每次frame重新加载(context创建)时都会加载一遍,CEF程序可以在OnContextCreated()给每一个frame设置不同的变量值。

CefRefPtr<CefBrowser> browser,

CefRefPtr<CefFrame> frame,

CefRefPtr<CefV8Context> context) {

// Retrieve the context's window object.

CefRefPtr<CefV8Value> object = context->GetGlobal();

// Create a new V8 string value. See the "Basic JS Types" section below.

CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");

// Add the string to the window object as "window.myval". See the "JS Objects" section below.

object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);

}

JavaScript in the frame can then interact with the window bindings.

<script language="JavaScript">

alert(window.myval); // Shows an alert box with "My Value!"

</script>

3.1.3         扩展方式(Extension)实现CEF设置JavaScript的变量

Extension方式和窗口绑定方式类似,但是Extension方式是为每一个frame加载到上下文context,一旦加载变不能在修改,没有加载之前,DOM是不存在的,尝试范围这个值的DOM会出现崩溃。Extension方式是在CefRenderProcessHandler::OnWebKitInitialized()函数中用CefRegisterExtension() 函数注册的,是在初始化函数中实现的,所以对于每一个frame都是一样的。

void MyRenderProcessHandler::OnWebKitInitialized() {

// Define the extension contents.

std::string extensionCode =

"var test;"

"if (!test)"

"  test = {};"

"(function() {"

"  test.myval = 'My Value!';"

"})();";

// Register the extension.

CefRegisterExtension("v8/test", extensionCode, NULL);

}

JS中调用变量值

<script language="JavaScript">

alert(test.myval); // Shows an alert box with "My Value!"

</script>

3.1.4         窗口绑定方式实现CEF给JavaScript提供函数

(1)   自定义类实现CefV8Handler类,实现Execute接口,JavaScript执行函数后,会将函数名称、参数和返回值引用传递给Execute函数,Execute函数根据函数名去调用函数,函数的具体实现在Execute中,然后执行返回返回值。

class MyV8Handler : public CefV8Handler {

public:

MyV8Handler() {}

virtual bool Execute(const CefString& name,

CefRefPtr<CefV8Value> object,

const CefV8ValueList& arguments,

CefRefPtr<CefV8Value>& retval,

CefString& exception) OVERRIDE {

if (name == "myfunc") {

// Return my string value.

retval = CefV8Value::CreateString("My Value!");

return true;

}

// Function does not exist.

return false;

}

// Provide the reference counting implementation for this class.

IMPLEMENT_REFCOUNTING(MyV8Handler);

};

(2)将函数名称设置到窗口对象,提供接受调用的handle

void MyRenderProcessHandler::OnContextCreated(

CefRefPtr<CefBrowser> browser,

CefRefPtr<CefFrame> frame,

CefRefPtr<CefV8Context> context) {

// Retrieve the context's window object.

CefRefPtr<CefV8Value> object = context->GetGlobal();

// Create an instance of my CefV8Handler object.

CefRefPtr<CefV8Handler> handler = new MyV8Handler();

// Create the "myfunc" function.

CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);

// Add the "myfunc" function to the "window" object.

object->SetValue("myfunc", func, V8_PROPERTY_ATTRIBUTE_NONE);

}

(3)JavaScript执行函数调用,就会进入Execute函数,返回返回值,alert会以弹窗形式展示结果。

<script language="JavaScript">
alert(window.myfunc()); // Shows an alert box with "My Value!"
</script>

3.1.5         Extension方式实现CEF给JavaScript提供函数

JavaScript调用CEF中的函数步骤:

(1)实现app类,继承与CefApp,重写OnWebKitInitialized,在OnWebKitInitialized函数内部使用字符串定义函数。CEF调用CefRegisterExtension函数向JavaScript注册函数,并提供处理调用的handler。

//CefClientApp.h

class CCefClientApp : public CefApp, public CefBrowserProcessHandler, CefRenderProcessHandler

{

public:

CCefClientApp();

~CCefClientApp();

//所有的CEF接口 都需要重载GetXXXHandler,并且return this,才会有效

virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() override { return this; }

//===========CefRenderProcessHandler

virtual void OnWebKitInitialized() override;

private:

CefRefPtr<CCEFV8HandlerEx> v8Handler_;

// Include the default reference counting implementation.

IMPLEMENT_REFCOUNTING(CCefClientApp);

private:

};

//CefClientApp.cpp

void CCefClientApp::OnWebKitInitialized()

{

//MessageBox(NULL,L"OnWebKitInitialized\n",0,0);

std::string app_code =

//-----------------------------------

//声明JavaScript里要调用的Cpp方法

"var app;"

"if (!app)"

"  app = {};"

"(function() {"

//  jsInvokeCPlusPlus 实例函数

"  app.jsInvokeCPlusPlus = function(v1, v2) {"

"    native function jsInvokeCPlusPlus();"

"    return jsInvokeCPlusPlus(v1, v2);"

"  };"

//函数

"  app.jsTransform = function(v1) {"

"    native function jsTransform();"

"    return jsTransform(v1);"

"  };"

"})();";

// Register app extension module

// JavaScript里调用app.jsInvokeCPlusPlus时,就会去通过CefRegisterExtension注册的CefV8Handler列表里查找

// 找到"v8/app"对应的CCEFV8HandlerEx,就调用它的Execute方法

// 假设v8Handler_是CCefClientApp的一个成员变量

//v8Handler_ = new CCEFV8HandlerEx();

CefRegisterExtension("v8/app", app_code, v8Handler_);

}

(2)JavaScript调用函数

<html>

<script>

app.jsInvokeCPlusPlus("123","xyz");

app.jsTransform("hello world");

</script>

</html>

(3)    handler的Execute函数接收调用响应,根据函数名称判断是调用哪个函数,获取参数调用函数。

//CEFV8HandlerEx.h
 
class CCEFV8HandlerEx : public CefV8Handler {
public:
    CCEFV8HandlerEx();
    ~CCEFV8HandlerEx();
public:
    virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception) override;
private:
    // Map of message callbacks.
    typedef std::map<std::pair<std::string, int>, std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value> > >CallbackMap;
    CallbackMap callback_map_;
 
 
public:
    IMPLEMENT_REFCOUNTING(CCEFV8HandlerEx);
};
 
//CEFV8HandlerEx.cpp
 
//JS调用C++函数的回调
bool CCEFV8HandlerEx::Execute(const CefString& name  /*JavaScript调用的C++方法名字*/, CefRefPtr<CefV8Value> object /*JavaScript调用者对象*/, const CefV8ValueList& arguments /*JavaScript传递的参数*/, CefRefPtr<CefV8Value>& retval /*返回给JS的值设置给这个对象*/, CefString& exception/*通知异常信息给JavaScript*/)
{
    if (name == _T("jsInvokeCPlusPlus"))
    {
        if (arguments.size() == 2)
        {
            CefString strParam1 = arguments.at(0)->GetStringValue();
            CefString strParam2 = arguments.at(1)->GetStringValue();
 
            TCHAR szBuffer[512];
            StringCbPrintf(szBuffer, sizeof(szBuffer), _T("jsInvokeCPlusPlus(%s,%s)"), strParam1.c_str(), strParam2.c_str());
            ::MessageBox(GetForegroundWindow(), szBuffer, _T("jsInvokeCPlusPlus"), MB_OK);
            retval = CefV8Value::CreateInt(0);
        }
        else
        {
            retval = CefV8Value::CreateInt(2);
        }
 
        return true;
 
    }
 
    if (name == L"jsTransform") {
        CefString strParam1 = arguments.at(0)->GetStringValue();
        TCHAR szBuffer[512];
        StringCbPrintf(szBuffer, sizeof(szBuffer), _T("jsTransform(%s)"), strParam1.c_str());
        ::MessageBox(GetForegroundWindow(), szBuffer, _T("jsTransform"), MB_OK);
    }
    return false;
}

自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

https://www.cnblogs.com/bclshuai/p/11380657.html

CEF(Chromium Embedded Framework和JavaScript交互相互调用函数和设置数据相关推荐

  1. Chromium Embedded Framework (CEF)

    Chromium Embedded Framework (CEF)是个基于Google Chromium项目的开源Web browser控件,支持Windows, Linux, Mac平台.除了提供C ...

  2. QT与JavaScript交互/Qt调用JS脚本

    QT与JavaScript交互/Qt调用JS脚本 简介 QT中调用JS函数 JS中调用QT函数 完整代码 mainwindow.h mainwindow.cpp html.html Qt调用JS脚本 ...

  3. Chromium Embedded Framework中文文档 (如何链接不同的运行时)

    简介 Visual Studio支持不同的运行时库,不同的库通过标记 /MD, /MT 和 /LD来区分,默认情况下,CEF使用/MT标记,Chromium也是如此,不过有时可能有些应用需要不同的运行 ...

  4. html onblur 函数执行了2次,JavaScript“onblur事件”调用函数失效 原因与解决方法

    由于JavaScript事件有很多,例如: 鼠标事件:onclick 键盘事件:onkeydown.onkeypress 表单事件:onblur.onchange 窗口事件属性:onerror.onl ...

  5. Chromium Embedded Framework中文文档之(基本使用)

    一般用法 使用CEF便捷的创建一个全功能的内建浏览器如下所示: // Define an instance of our CefHandler implementation. Various meth ...

  6. Chromium Embedded Framework中文文档 (SVN属性)

    Subversion properties 在CEF开发中,应当如下将Subversion配置文件配置成自动设置新文件的属性,不要使用svn:eol-style=native因为它会使得不同平台间的文 ...

  7. C# winform与Javascript的相互调用

    <html> <head> <meta http-equiv="Content-Language" content="zh-cn" ...

  8. 关于python中自己写的模块之前相互调用函数

    PS:之前偷懒直接用了添加系统路径的方法,现在代码越改越多也越杂,而且最近要添加多个配置参数,当我添加完参数发现崩了,服务计算一直失败,还是得用导包的形式,之前稍微用过但是一直模棱两可一知半解,现在知 ...

  9. 安卓开发笔记(二十二):读取本地(内置)html文件并实现和Javascript交互

    实际上我们通常是使用WebView控件对本地html进行读取,这样就可以体会类似web app和安卓原生混合开发的乐趣了.在读取本地html并展示在前台的时候,并不需要在Androidmenifast ...

最新文章

  1. 整合quickx到普通cocos2dx
  2. 一个MySQL锁和面试官大战三十回合,我霸中霸!
  3. 新书上市 | 新视角来了:《用户体验四维度》
  4. 列表渲染 wx:key 的作用、条件渲染 wx:if 与 hidden 的区别
  5. 解决The current branch is not configured for pull No value for key branch.master.merge found in confi
  6. add binary java_LeetCode算法题-Add Binary(Java实现)
  7. Visual Studio的导入和导出设置
  8. 疯狂ios讲义疯狂连载之实现游戏视图控制器
  9. OJ1057: 素数判定(C语言经典列题,判断变量的应用)
  10. nginx优缺点 优化
  11. 数字交易所内存撮合、无锁并发技术源码
  12. 万年历c语言编程代码解释,自己写的c语言万年历代码
  13. ubuntu安装nvidia显卡驱动
  14. WinDriver_资料
  15. php 去零取整,php取整的几种方法
  16. 无线路由器无线桥接(一)
  17. 我国计算机通信技术现状及未来的发展趋势,概述计算机通信技术的发展趋势
  18. 06 聚类算法 - 代码案例二 - K-Means算法和Mini Batch K-Means算法比较
  19. 最新 NCBI 上传测序数据教程 (图文详解)
  20. SQL数据分析淘宝用户分析实操

热门文章

  1. linux能修改用户的权限,linux怎样修改用户权限
  2. 大数据-孩子学习成绩分析
  3. This means it will render an <Outlet /> with a null value by default resulting in an “empty“ page.
  4. 与IBM谈判搁浅 Sun及其CEO前景存疑
  5. 智能背包的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  6. NeHe OpenGL第二十九课:Blt函数
  7. RocketChip
  8. C语言-快速回忆_float和double的输入输出格式
  9. 我只是还没有全力以赴
  10. 如何在没有联网的情况下使用maven本地仓库进行开发