CefClient提供所有浏览器事件处理的接口,重写CefClient类中的方法处理浏览器事件:包括Browser的生命周期,右键菜单,对话框,状态通知显示,下载事件,拖曳事件,焦点事件,键盘事件,离屏渲染事件等,对Cef进行行为控制的方法一般都集中在这些接口。

/*

注册浏览器生命周期的事件类CefLifeSpanHandler的实例。

重写CefLifeSpanHandler接口类中的方法实现对browser对象周期回调事件的处理:

*/

virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() { return NULL;}

//当新browser对象被创建后马上触发,重写此方法保存所有创建的browser对象的指针。

void OnAfterCreated(CefRefPtr<CefBrowser> browser)

//当调用CloseBrowser函数后触发

bool DoClose(CefRefPtr<CefBrowser> browser)

//当browser对象被销毁前触发,必须重写此方法且完成释放对所有browser对象的指针。

void OnBeforeClose(CefRefPtr<CefBrowser> browser)

② 

//当window render无法完成时采用离屏渲染,重写CefRenderHandler类中的方法实现离屏渲染回调事件的处理:

virtual CefRefPtr<CefRenderHandler> GetRenderHandler() { return NULL; }

//根窗口创建后触发,通过此接口可获取根窗口在屏幕的位置坐标。

bool GetRootScreenRect(CefRefPtr<CefBrowser> browser, CefRect& rect) { return false; }

//当browser对象初始化或者大小改变时触发,通过此接口获取browser对象在窗口的位置坐标。

bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect)=0

③ 

virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() {return NULL;}

Browser对象显示状态的事件处理。

④  

virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() { return NULL;}

与JavaScript dialogs相关的回调事件的处理,CefJSDialogHandler接口类中的方法在UI线程中调用。

⑤ 

virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefProcessId source_process,CefRefPtr<CefProcessMessage> message) {return false;}

进程间通信接口,实现browser进程和render进程间的通信。当收到其他进程的消息时触发,当消息被处理后返回true。此回调函数外不可使用其他进程的消息或此消息的引用。

其他浏览器的回调事件(拖拽、下载、查找、焦点、键盘等)都在CefClient类中有对应的注册接口。

CefApp负责进程的实例化及退出。重写Cef类中的GetBrowserProcessHandler()及GetRenderProcessHandler()方法创建browser进程及render进程的实例。

CefBrowser及CefFrame为不可实例化的抽象类。其中,CefBrowser类表示一个浏览器窗口,CefFrame类表示浏览器窗口中的一块区域,一个浏览器窗口可包含多个Frame块。两者中的方法在browser进程中使用时一般可在所有线程中使用,在render进程中一般只能在主线程中使用。

  启动Render进程:

1)  单一执行:browser主进程调用CefExcuteProcess()方法之后创建render子进程。分析CefExcuteProcess()方法的代码:首先根据命令行参数的type参数,如果为NULL,说明为主进程,返回-1,回到主程序,执行创建窗口等主进程代码。如果不为NULL,会在chrome代码里创建render进程。

2)  独立子进程执行:需要两个分开的工程和分开的入口函数。在主程序中的CefSettings settings中增加CefString(&settings.browser_subprocess_path)=子进程执行路径。

JS加载及与Cef的交互由Render进程处理,因此CefApp的GetRenderProcessHandler()方法必须提供实现,否则OnContextCreate()和OnWebktiInitialized()接口无法被调用。定义类继承自CefApp和CefRenderProcessHandler,重写CefApp中的GetRenderProcessHandler()方法并返回render进程实例的指针。CefRenderProcessHandler中的OnContextCreate()接口会在Frame的context创建后被调用,提供js与Cef代码交互的功能。

Cef基于Chrome,Chrome使用v8jsEngine执行内部的js。根据v8的规范,执行一段js代码必须显式指定context,因此在调用js代码的时候必须先进入context,而每一个Frame有属于自己的context,每一次Frame加载都会调用OnContextCreate()方法。

1)  Cef调用JS:

Cef代码可以通过调用CefFrame::ExecuteJavaScript()方法执行js代码。

frame->ExecuteJavaScript(const CefString& jsCode,const CefString& frame->GetURL(), int startLine);

context所在的CefRefPtr<CefFrame> frame和CefRefPtr<CefBrowser> browser在OnContextCreate()接口中获取。

2)  JS调用Cef

①重写OnContextCreate()方法,从OnContextCreate()接口提供的context中通过context-GetGlobal()获取window对象,window对象声明为cefV8Value类型(相当于js中所有对象和值都以var声明)。通过window-> SetValue(const CefString& key, CefRefPtr<CefV8Value> value, PropertyAttribute attribute)方法实现绑定该窗口对象下某一个CefV8Value类型对象(方法中参数value)和一特定标识符(方法中参数key)。

用来绑定的CefV8Value类型对象包含js基本数据类型(int,double,string,bool等)用CefV8Value::Create静态方法创建,例如string类型用CefV8Value::CreateString创建;以及js数组和对象类型,用静态方法CefV8Value::CreateArray()或CefV8Value::CreateObject ()创建。

②用来绑定的CefV8Value类型对象可以是函数对象定义一个类(例如MyCefV8Handler)继承自CefV8Handler,

利用

CefRefPtr<MyCefV8Handler> handler (new MyCefV8Handler());

CefV8Value func=CefV8Value::CreateFunction(const CefString& name, CefRefPtr<CefV8Handler> handler) 方法创建函数对象并调用window-> SetValue()进行绑定。CreateFunction传入的参数为函数名和实例化的MyCefV8Handler对象,并且在MyCefV8Handler类中必须重写CefV8Handler中的Execute()方法判断js调用的Cef方法并接收参数及传递返回值。

JS调用Cef中的方法示例代码:

//自定义SimRender类继承CefApp类和CefRenderProcessHandler类

class simpleRender :public CefApp, public CefRenderProcessHandler

{

public:

//重写GetRenderProcessHandler方法,render进程启动时被唤醒来创建render进程的示例

void CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE

{

return this;

}

//重写OnContextCreated方法,每一次Frame加载都会调用OnContextCreate()方法,绑定window对象

void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE

{

//获取window对象

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

//创建MyCefV8Handler对象实例

CefRefPtr<MyCefV8Handler> handler(new MyCefV8Handler());

//创建函数对象myFunc

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

//绑定函数对象myFunc和以标识符“func”,js通过window.func调用Cef代码

window->SetValue(_T("func"), myFunc, V8_PROPERTY_ATTRIBUTE_NONE);

}

}

//自定义MyCefV8Handler类继承CefV8Handler类

class MyCefV8Handler :public CefV8Handler

{

public:

//重写Execute方法判断js调用的Cef方法

bool  Execute(const CefString& func_name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception)

{

if (func_name == _T("func"))

{

retval = CefV8Value::CreateString(_T("func: C++!"));

return true;

}

return false;

}

}

js中:

<script type="text/javascript">

Function f()

{

var retval=window.func();

window.alert(retval);

}

</script>

CEF和JS交互的更多相关文章

  1. WPF内嵌CEF控件,与JS交互

    1)安装cefsharp.winform包 打开VS2017,打开nuget,找到cefsharp.winform,安装 问:为什么wpf程序不使用cefsharp.wpf? 答:因为cefwpf 4 ...

  2. 【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析

    作者: 牛A与牛C之间 时间: 2013-12-12 分类: 技术文章 | 2条评论 | 编辑文章 主页 » 技术文章 » 第7篇:Xilium CefGlue 关于 CLR Object 与 JS ...

  3. Winform 通过 WebBrowser 与 JS 交互

    Winform 通过 WebBrowser 与 JS 交互 魏刘宏 2019.08.17 之前在使用 Cef (可在 Winform 或 WPF 程序中嵌入 Chrome 内核的网页浏览器的组件)时, ...

  4. 关于JS交互--调用h5页面,点击页面的按钮,分享到微信朋友圈,好友

    关于js交互,在iOS中自然就想到了调用代理方法 另外就是下面的,直接上代码了: 如果你的后台需要知道你的分享结果,那么,就在回调里面调用上传到服务器结果的请求即可

  5. webView和js交互

    与 js 交互 OC 调用 JS // 执行 js - (void)webViewDidFinishLoad:(UIWebView *)webView { NSString *title = [web ...

  6. 李洪强iOS经典面试题147-WebView与JS交互

    李洪强iOS经典面试题147-WebView与JS交互   WebView与JS交互 iOS中调用HTML 1. 加载网页 NSURL *url = [[NSBundle mainBundle] UR ...

  7. WebView---Android与js交互实例

    Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true 原文地址:http://blog.csdn.net/it10 ...

  8. iOS与JS交互实战篇(ObjC版)

    前言 ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了.这里只介绍iOS7.0后出来的JavaScriptCore framework. 关于JavaS ...

  9. Android WebView加载本地html并实现Java与JS交互

    最近做的一个项目中,用到自定义地图,将自定义地图转换成html页面,现在需要做的是如何将本地的html加载到android中,并可以实现交互. 相关讲解: 其实webview加载资源的速度并不慢,但是 ...

随机推荐

  1. Linux 大页面使用与实现简介(转)

    引言 随着计算需求规模的不断增大,应用程序对内存的需求也越来越大.为了实现虚拟内存管理机制,操作系统对内存实行分页管理.自内存“分页机制”提出之始,内存页面的默认大小便被设置为 4096 字节(4KB ...

  2. Edison UVALive3488

    传送门 题目大意 有一个0~n-1的序列,有m次操作,操作包含三个元素:pl,len,ti,表示这个操作进行ti次,每次将从pl+1开始的len个元素移到序列头部.分析 看到题不难想到使用平衡树将需移 ...

  3. input 输入框两种改变事件的方式

    一.在输入框内容变化的时候不会触发,当鼠标在其他地方点一下才会触发 $('input[name=myInput]').change(function() { ... }); 二.在输入框内容变化的时候 ...

  4. Linux下面的IO模型

    1. Linux下的五种I/O模型 阻塞I/O模型: 一直阻塞      应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空 ...

  5. Altium designer的PCB设计规则

    PCB布线规则,布板需要注意的点很多,但是基本上注意到了下面的这此规则,LAYOUT PCB应该会比较好,不管是高速还是低频电路,都基本如此. 1. 一般规则 1.1 PCB板上预划分数字.模拟.DA ...

  6. 常用Linux命令:ls/cd/pwd/mkdir/rm/mv/cp

    一.ls:列出目标目录中所有的子目录和文件 1.命令格式 ls [选项] [目录名] 2.常用参数 -a :列出目录下所有文件 -h :以容易理解的格式列出文件大小 -l  :除了文件名之外,还将文件 ...

  7. python 趣味强制请吃饭

    # -*- coding: utf-8 -*- import easygui who = easygui.buttonbox("你想请谁吃饭 ?", "luckly qu ...

  8. Hadoop单机/伪分布式集群搭建(新手向)

    此文已由作者朱笑笑授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文主要参照官网的安装步骤实现了Hadoop伪分布式集群的搭建,希望能够为初识Hadoop的小伙伴带来借鉴意 ...

  9. 选择性搜索(Selective Search)

    1 概述 本文牵涉的概念是候选区域(Region Proposal ),用于物体检测算法的输入.无论是机器学习算法还是深度学习算法,候选区域都有用武之地. 2 物体检测和物体识别 物体识别是要分辨出图 ...

  10. ubuntu - 14.04,必须会的技能-安装PPA源中的程序,更大范围使用deb格式安装文件!!

    在使用ubuntu时候,管理各种软件最方便的方式肯定是使用软件中心了,这个管理工具类似windows的 程序管理了,使用它有两个好处: 1,无需处理包依赖,linux里面程序存在各种依赖关系,这在以往 ...