CEF学习质料

2023-05-16

目录

 

一、编译CEF3里的lib:

   1.下载CEF3

   http://opensource.spotify.com/cefbuilds/index.html

   2.下载CMake,运行CMake_GUI.exe

   3.CMake设置CEF3的Sources文件夹路径,与新new build路径后,点击“Configure”

   4.选择编译平台,无后缀表示32位,ARM,Win64表示各自平台,这里我们选择VS2017位编译

   5.等待Configuring Done结束,点“Generate”按钮

注意路径中不能有'\',只能有'/',否则会提示“Invalid escape sequence \o”错误

   6.使用VS打开cef工程

 

二、开始在MFC中使用Cef3(多进程和单进程讲解):

1.新建一个MFC基础窗口程序

2.把Cef3 SDK里的文件整理出来,并放进自己工程文件夹里,整理出来的效果如图

3.配置工程属性

4.添加文件到工程

5.在MFC中正式写代码前还要做一件事,就是要先学习如何在纯Win32中使用CEF3!

         a.打开cef目录里的test/cefsimple

        b.学习cefsimple示例工程

        c.理解Cef3的多进程与单进程之间的关系

6.开始写Cef3的初始化代码

7.开始写创建Cef3窗口控件的代码

8.增加 多进程Release与单进程Debug之间的切换代码

成功运行!

 

三、难点及疑问解答

Q:为什么cefsimple Win32可以运行,直接复制到MFC中却运行不起来?

A:如果需要在MFC环境中运行,还需要在CEF3初始化的参数加上

 

Q:为什么调用CefShutdown会崩溃?

A:多进程模式下调用CefShutdown就是OK的,app也能够正常析构,而单进程模式调用CefShutdown会直接崩溃!

 

Q:为什么SimpleHandler这个类没有办法获取CefBrowser句柄?

A:自己增加两个函数就很方便啦

 


一、编译CEF3里的lib:

   1.下载CEF3

   http://opensource.spotify.com/cefbuilds/index.html

   2.下载CMake,运行CMake_GUI.exe

 

   3.CMake设置CEF3的Sources文件夹路径,与新new build路径后,点击“Configure”

   4.选择编译平台,无后缀表示32位,ARM,Win64表示各自平台,这里我们选择VS2017位编译

   

 

   5.等待Configuring Done结束,点“Generate”按钮

注意路径中不能有'\',只能有'/',否则会提示“Invalid escape sequence \o”错误

 

   6.使用VS打开cef工程

 

二、开始在MFC中使用Cef3(多进程和单进程讲解):

1.新建一个MFC基础窗口程序

2.把Cef3 SDK里的文件整理出来,并放进自己工程文件夹里,整理出来的效果如图

bin->x86->Debug来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\Debug

bin->x86->Release来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\Release

include来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\include

lib->x86->Debug来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\Debug 里的lib后缀文件

lib->x86->Release来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\Release 里的lib后缀文件

Resources来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\Resources

其他来源于:

D:\cef_binary_3.3626.1891.g52be333_windows32\tests\cefsimple

 

3.配置工程属性

 


   
   
  1. xcopy /e /r /y "$(ProjectDir)CEF3\bin\x86\Debug" "$(OutDir)"
  2. xcopy /e /r /y "$(ProjectDir)CEF3\Resources" "$(OutDir)"


   
   
  1. xcopy /e /r /y "$(ProjectDir)CEF3\bin\x86\Release" "$(OutDir)"
  2. xcopy /e /r /y "$(ProjectDir)CEF3\Resources" "$(OutDir)"

4.添加文件到工程

5.在MFC中正式写代码前还要做一件事,就是要先学习如何在纯Win32中使用CEF3!

 

         a.打开cef目录里的test/cefsimple

 

        b.学习cefsimple示例工程

       (里面每个文件都要认真看一遍,不然后面MFC的示例 你很难看懂原理)

 

 

        文件说明:

        cefsimple_win.cc:Win32主程序的main入口演示

        simple_handler.cc:Chrome浏览器控件的回调函数演示

        simple_handler.h

        simple_app.cc:初始化Chrome浏览器控件演示

        simple_app.h

        c.理解Cef3的多进程与单进程之间的关系

 

        在Debug模式中要使用单进程,只有Release模式中才使用多进程。

        因为CEF3多进程的时候Browser、Rendder等进程是独立分开的,在一些函数上打断点是打不进去的,无法调试!而单进程话就可以正常调试。好,明白了 就开始写代码

 

6.开始写Cef3的初始化代码

        (1).在程序入口InitInstance的最头部加上这段代码


   
   
  1. #pragma region 使用CEF3控件_仅支持32位编译环境
  2. #include "CEF3/simple_app.h"
  3. #include <include/cef_browser.h>
  4. #include <include/cef_command_line.h>
  5. #include <include/views/cef_browser_view.h>
  6. #include <include/views/cef_window.h>
  7. #include <include/wrapper/cef_helpers.h>
  8. #include "simple_handler.h"
  9. #ifdef _DEBUG
  10. #pragma comment(lib,"CEF3/lib/x86/Debug/libcef.lib")
  11. #pragma comment(lib,"CEF3/lib/x86/Debug/libcef_dll_wrapper.lib")
  12. #else
  13. #pragma comment(lib,"CEF3/lib/x86/Release/libcef.lib")
  14. #pragma comment(lib,"CEF3/lib/x86/Release/libcef_dll_wrapper.lib")
  15. #endif
  16. #pragma endregion

   
   
  1. #pragma region 初始化CEF3
  2. //CEF3程序入口
  3. CefEnableHighDPISupport();
  4. void* sandbox_info = NULL;
  5. CefMainArgs main_args(AfxGetApp()->m_hInstance);
  6. //初始化CEF3
  7. CefSettings settings;
  8. settings.no_sandbox = true;
  9. settings.multi_threaded_message_loop = true;
  10. #ifdef _DEBUG
  11. #else
  12. settings.log_severity = LOGSEVERITY_DISABLE; //禁用debug.log日志
  13. #endif
  14. CefRefPtr<SimpleApp> app(new SimpleApp);
  15. CefInitialize(main_args, settings, app.get(), sandbox_info);
  16. #ifndef _DEBUG //只有Release模式才启用多进程模式
  17. // CEF applications have multiple sub-processes (render, plugin, GPU, etc)
  18. // that share the same executable. This function checks the command-line and,
  19. // if this is a sub-process, executes the appropriate logic.
  20. int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);
  21. if (exit_code >= 0) {
  22. //The sub - process has completed so return here.
  23. return exit_code;
  24. }
  25. #endif
  26. #pragma endregion

         (2).在程序入口InitInstance的最部加上这段代码

 


   
   
  1. //关闭CEF
  2. CefShutdown();

 

7.开始写创建Cef3窗口控件的代码

        (1).在OnInitDialog加上这段代码


   
   
  1. //加载CEF3窗口控件
  2. RECT rt;
  3. GetClientRect(&rt); //获取自己窗口的大小
  4. CefWindowInfo window_info;
  5. window_info.SetAsChild(GetSafeHwnd(), rt); // cefsimple中的是用SetAsPopup,这里嵌入控件要用SetAsChild
  6. m_CefHandler = new SimpleHandler( false);
  7. std:: string url = "http://www.baidu.com";
  8. //std::wstring wurl = s2ws(url); //如果网址要有中文则需要用宽字节
  9. CefBrowserSettings browser_settings;
  10. CefBrowserHost::CreateBrowser(window_info, m_CefHandler, CefString(url), browser_settings,
  11. NULL);

        (2).在窗口的Dlg私有成员变量增加这句代码

CefRefPtr<SimpleHandler> m_CefHandler; // CEF3句柄管理
   
   

 

8.增加 多进程Release与单进程Debug之间的切换代码

        需要在simple_app.cc、simple_app.h中添加


   
   
  1. //simple_app.cc
  2. void SimpleApp::OnBeforeCommandLineProcessing(const CefString& process_type,
  3. CefRefPtr<CefCommandLine> command_line)
  4. {
  5. #ifdef _DEBUG //只在Debug模式使用单进程
  6. command_line->AppendSwitch( "single-process");
  7. #endif
  8. }
  9. void SimpleApp::OnContextInitialized()
  10. {
  11. CEF_REQUIRE_UI_THREAD();
  12. }

 

 

 

 


   
   
  1. //simple_app.h
  2. // CefBrowserProcessHandler methods:
  3. virtual void OnBeforeCommandLineProcessing(
  4. const CefString& process_type,
  5. CefRefPtr<CefCommandLine> command_line) OVERRIDE;
  6. // CefBrowserProcessHandler methods:
  7. virtual void OnContextInitialized() OVERRIDE;

 

成功运行!

 

三、难点及疑问解答

Q:为什么cefsimple Win32可以运行,直接复制到MFC中却运行不起来?

A:如果需要在MFC环境中运行,还需要在CEF3初始化的参数加上

CefSettings.multi_threaded_message_loop = true;

否则是运行不起来的!

原因在于Win32中的示例是调用CefRunMessageLoop()来处理CEF3的消息,

而MFC中已经有一个消息循环了,所以告诉CEF3让它自己处理消息循环。

CEF能整合现有的应用程序的消息循环替代自己的消息循环

有两种做法

1.定期调用CefDoMessageLoopWork() 替代调用CefRunMessageLoop()

每次调用CefDoMessageLoopWork() 将会执行一次CEF消息循环的迭代,小心使用这种方法。调用这个方法频率太少,将会饿死CEF消息循环并且消极的影响浏览器的性能。调用这种方法太频繁将会消极的影响CPU的使用

2.设置

CefSettings.multi_threaded_message_loop = true(仅限windows下使用),

这将导致CEF运行在浏览器UI线程,该UI线程是从主应用程序分离出来的线程。这种方法既不需要调用CefDoMessageLoopWork() 也不需要调用 CefRunMessageLoop() 。

CefInitialize() 和CefShutdown()这两个函数仍然需要在主应用程序调用。你需要提供你自己的机制和主应用程序线程交流。在cefclient_win.cpp查看消息的使用示例.你可以在windows下使用命令行 “–multi-threaded-message-loop”测试cefclient模式。

 

Q:为什么调用CefShutdown会崩溃?

A:多进程模式下调用CefShutdown就是OK的,app也能够正常析构,而单进程模式调用CefShutdown会直接崩溃!

 

Q:为什么SimpleHandler这个类没有办法获取CefBrowser句柄?

A:自己增加两个函数就很方便啦


   
   
  1. //simple_handle.h
  2. public:
  3. // 返回第一个浏览器控件CefBrowser指针(自定义函数)
  4. CefRefPtr<CefBrowser> GetCefBrowser(int nIndex);
  5. //获取共有多少个CEF浏览控件窗口
  6. int GetCefBrowserCount();

 


   
   
  1. //simple_handle.cc
  2. // 返回第一个浏览器控件CefBrowser指针(自定义函数)
  3. CefRefPtr<CefBrowser> SimpleHandler::GetCefBrowser(int nIndex)
  4. {
  5. if (browser_list_.empty())
  6. {
  7. return NULL;
  8. }
  9. BrowserList::iterator bit = browser_list_.begin();
  10. for ( int i = 0; i < nIndex ; i++)
  11. {
  12. bit++;
  13. }
  14. return (*bit);
  15. }
  16. //获取共有多少个CEF浏览控件窗口
  17. int SimpleHandler::GetCefBrowserCount()
  18. {
  19. int n = 0;
  20. BrowserList::iterator bit = browser_list_.begin();
  21. for (; bit != browser_list_.end(); ++bit)
  22. {
  23. n++;
  24. }
  25. return n;
  26. }

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CEF学习质料 的相关文章

  • 运维人员核心职责

    运维小知识点 xff01 网站数据不能丢网站7 24小时运转提升用户体验 xff0c 访问速度要快 云计算 1 公有云 2 私有云 就是自己内部的运维工程师部署的一个云平台 xff0c 资源管理平台数据都放在自己手中 xff0c 不被别人看
  • Ubuntu16.04下向github传送或修改代码

    初次使用Git设置 这段针对的是初次使用Git的设置 xff0c 如果初次设置之后 xff0c 就直接跳到下一阶段 将本地仓库push至github远程仓库 1 首先要确定Ubuntu下是否有git 终端运行指令 sudo apt inst
  • 字符串尾部得加'\0'原因

    39 0 39 一般放在字符串的结束处 xff0c 表示字符串的结束 xff0c 其是ascii值为0的字符的转义 在头文件 include lt string h gt 中包含的一些字符串处理函数等中 xff0c 一般处理字符串时 xff
  • cmake-CMakeLists.txt中添加目标编译选项的方法

    CMakeLists txt中添加目标编译选项的方法 原因 xff1a 如果程序中用到了宏来区分不同的方法 xff0c 但是又不想每次在用到不同的方法的时候都要在程序中更改宏定义后再进行编译 xff0c 那么可以在CMakeLists tx
  • GDB多线程调试和死锁

    set schedular locking on off 条件断点查看循环中的某些变量 break if命令 示例 xff1a break test c 34 if x amp y 61 61 1 默认情况下我们执行到断点处继续执行时 xf
  • Gazebo仿真踩坑系列-乱飞、抖动等

    本文章记录机械臂 塔吊等仿真过程中遇到的各种问题 塔吊建模 前言 gazebo机械臂等控制仿真最重要的是建模 xff0c 也就是URDF的编写 xff0c 而这里面有着特别多要注意的地方 xff0c 否则会发生 启动乱飞 控制乱飞 和 启动
  • Qt6新创建CMake项目启动不了

    错误如下 xff1a 1 error CMake was unable to find a build program corresponding to 34 Ninja 34 CMAKE MAKE PROGRAM is not set Y
  • Linux/Centos 安装oracle报错“调用makefile ‘/oracle/product/11.2.0/dbhome_1/sysman/lib/ins_emagent.mk的目标” 解决

    解决centos7 redhat7安装oracle11g到 70报错问题 Linux Centos 安装oracle报错 调用makefile 39 oracle product 11 2 0 dbhome 1 sysman lib ins
  • C++使用技巧(四):单双冒号“:”和“::”用法

    C 43 43 单冒号与双冒号的作用 1 冒号 xff08 xff09 用法 xff08 1 xff09 表示结构体内位域的定义 xff08 即该变量占几个bit空间 xff09 span class token keyword typed
  • 交换机与路由器

    交换机 VS 路由器 交换机 xff1a 把数据包发送到正确的位置 xff0c 相当于邮递员 xff0c 根据数据包中的目标mac地址 xff0c 找到他对应的物理端口 xff0c 一台交换机有很多个端口 xff0c 它们都有自己的编号 x
  • 在C++中使用openmp进行多线程编程

    声明 xff1a 本文是基于Joel Yliluoma写的Guid into OpenMP Easy multithreading programming for C 43 43 而写的 xff0c 基本是按照自己的理解 xff0c 用自己
  • CMakeLists 写法总结

    0 前言 之前简单介绍了makefile的写法 xff0c 但实际工程中基本不会手写makefile xff0c 通常情况是会写一个CMakeLists甚至是多层多个CMakeLists来构建整个工程 关于makefile和CMakeLis
  • C++成员函数后面跟冒号冒号

    冒号后面跟的是赋值 xff0c 这种写法是C 43 43 的特性 A int aa int bb a aa b bb 相当于 A int aa int bb a 61 aa b 61 bb
  • Apollo 算法阅读之Public Road轨迹规划算法--路径规划(含源代码)

    本次博文主要介绍apollo 5 0版本内使用的轨迹规划算法 public road xff0c 该算法的核心思想是PV解耦 xff0c 即Path Velocity的解耦 xff0c 其主要包含两个过程 xff1a 1 路径规划 xff0
  • 交互式多模型 IMM的原理

    交互式多模型简单原理 交互式多模型 IMM xff08 Interacting Multiple Model xff09 控制算法的主体思想是基于贝叶斯理论而提出的模型间的自动识别与切换 xff1a 在任意跟踪时刻 xff0c 通过设置对应
  • Apollo算法阅读之基于Sqp的Referenceline全局参考路线优化(含源码)

    算法来源于Apollo代码 代码源地址 xff0c 通过序列优化思想 xff0c 建立无人驾驶车辆参考路径的平滑 xff0c 利用泰勒展开将曲率约束线性化表达 xff0c 目标函数中利用弹性带思想 xff0c 并尽可能缩短参考路径长度且保持
  • 离散点间曲率计算

    本文转自知乎计算离散点的曲率 xff08 附Python MATLAB代码 xff09 在很多学科中的很多计算任务中都需要用到曲线的曲率 xff08 或者曲率半径 xff09 xff0c numpy库里和matlab build in里都没
  • 关于Frenet坐标系内曲率约束

    本文摘自于apollo直播公开课 xff0c 因为车辆存在最小的转弯半径 xff0c 所以我们要对车辆运动学进行限制 由于转弯半径是基于笛卡尔坐标系的 xff0c 需要基于Frenet坐标系进行转换 假设 xff1a xff0c 车辆朝向与
  • caffe内CHECK_EQ等函数意义解释

    个人在学习caffe源码文件时遇到了CHECK EQ函数 xff0c 不理解什么含义 xff0c 经过上下文理解 xff0c 明白了其中含义 CHECK EQ x y lt lt 34 x 61 y 34 xff0c EQ即equation
  • 电路交换方式与分组交换方式计算题

    已知网络速率为1Mb S xff0c 对于每个用户来说 xff0c 有10 的时间是活跃的 xff0c 活跃时网速为100kb s 对于电路交换方式来说 xff0c 最多只能支持10位用户接入网络 由于1Mb 61 1000kb xff0c

随机推荐

  • Carla编译make launch过程中出现UE4_ROOT is not defined

    在编译carla过程中出现如下情况 xff1a BuildCarlaUE4 sh ERROR UE4 ROOT is not defined or points to a non existant directory please set
  • request 模块可以帮助我们发起http请求

    request 模块可以帮助我们发起http请求 步骤 xff1a 1 首先import 下 request 模块 2 然后看请求的方式 xff0c 选择对应的请求方法 3 接受返回的报文信息 有requests get requests
  • 自动提取论文公式方法

    需要的软件 MathType 7 Mathpix Snipping Tool 软件获取链接 xff1a 链接 xff1a https pan baidu com s 1Fz VGkgZJbZhlocL4y1AoA 提取码 xff1a ci0
  • 现代 CMake 简明教程--CMake 基础

    前言 用 CMake 来构建 C C 43 43 项目是业内的主流做法 最近 xff0c 我们的项目代码做了一些拆分和合并 xff1a 引入其他仓库代码 xff0c 并且将公共部分拆分以供多个仓库同时使用 为此 xff0c 就得修改项目中的
  • USB接线定义和链接摄像头

    原文链接 xff1a https www cnblogs com chinalantian articles 2131361 html 写本文的意义在于了解USB的接线定义和实现使用手机数据线读取摄像头图像 USB接口定义 颜色 一般的排列
  • C++小结 析构函数、函数后面接冒号 等等

    讲在前面 本小结有析构函数 C 43 43 函数后面接 xff1a 的含义 C 43 43 中public protected及private用法 条件运算符 fabs 和abs 区别 C 43 43 中的结构体内的函数 类中成员函数声明后
  • C++学习笔记:子类构造函数中冒号的使用 — 同时创建父类和子类对象

    C 43 43 中 xff0c 子类对象创建需要预先创建父类对象 xff0c 对象销毁顺序与此相反 假如父类构造函数只存在有参构造 xff0c 在子类对象实例化之前 xff0c 便需要创建一个父类对象 xff0c 在不存在默认无参构造情况下
  • C语言头文件详解

    1 include的作用 简单一句话 xff1a 在include的地方 xff0c 把头文件里的内容原封不动的复制到引用该头文件的地方 2 头文件的引用 头文件引用有两种形式 xff1a include lt stdio h gt 和 i
  • 字符数组进行复制需要加结束符‘\0’

    如想将str1数组内容复制到str2中 xff08 不用strcpy xff0c 如果按照以下格式复制 xff09 xff0c 需要加字符结束符 0 xff1b span class token macro property span cl
  • 学习Kafka

    1 Kafka是什么 xff1f 学习Kafka的目的 xff0c 为了解决高吞吐量项目的需求 xff0c Kafka号称大数据的杀手锏 xff0c 这款为大数据而生的消息中间件 xff0c 以其百亿级tps的吞吐量名声大噪 xff0c 迅
  • cmake命令之option使用案例

    option的命令形式如下 option lt variable gt 34 lt help text gt 34 value option简介 cmake中option起到编译开关的作用 xff0c CMakeLists txt中opti
  • docker学习

    现代软件开发的一大目的就是隔离 xff0c 应用程序在运行时相互独立互不干扰 xff0c 这种隔离实现起来是很不容易的 xff0c 其中一种解决方案就是上面提到的虚拟机技术 xff0c 通过将应用程序部署在不同的虚拟机中从而实现隔离 但是虚
  • 3.编写CMakeLists文件

    本章将介绍为您的软件编写有效的 CMakeLists 文件的基础知识 它将涵盖处理大多数项目所需的基本命令和问题 虽然 CMake 可以处理极其复杂的项目 xff0c 但对于大多数项目 xff0c 你会发现本章的内容会告诉你所有你需要知道的
  • boost库简介

    欢迎来到boost org Boost 提供免费的经过同行评审的可移植 C 43 43 源库 我们强调与 C 43 43 标准库配合良好的库 Boost 库旨在广泛使用 xff0c 并可用于广泛的应用程序 Boost 许可证鼓励所有用户以最
  • 解决mavros源码安装过程中wstool update -t src -j4报错(网络限制)问题

    继上一篇解决了mavlink安装的网络问题后 xff0c 没想到这个指令更新也需要链接到github 而直接执行时 xff0c 报错 xff1a span class token punctuation span mavlink span
  • QT事件详解

    一 简介 在Qt中 xff0c 事件作为一个对象 xff0c 继承自 QEvent 类 xff0c 常见的有键盘事件 QKeyEvent 鼠标事件 QMouseEvent 和定时器事件 QTimerEvent 等 xff0c 与 QEven
  • QT事件系统之二:鼠标事件和滚轮事件

    一 QMouseEvent的详细描述 QMouseEvent 类用来表示一个鼠标事件 xff0c 当在窗口部件中按下鼠标 释放鼠标和移动鼠标指针时 xff0c 都会产生鼠标事件 QMouseEvent 利用 QMouseEvent 类可以获
  • Qt事件系统之三:键盘事件

    QKeyEvent类用来描述一个键盘事件 当键盘按键被按下或者被释放时 xff0c 键盘事件便会被发送给拥有键盘输人焦点的部件 QKeyEvent的key 函数可以获取具体的按键 xff0c 对于Qt中给定的所有按键 xff0c 可以在帮助
  • 第一个自己写的程序

    22年8月份花了三周时间快速过了一遍某站一位大佬的视频 xff0c 前几天刷朋友圈时偶然看见一位道友写了个矩阵乘积的计算器 xff0c 瞬间给了我灵感 xff0c 直接开始操作 理想很丰满 xff0c 现实很扯淡 xff0c 刚开始写了个4
  • CEF学习质料

    目录 一 编译CEF3里的lib xff1a 1 下载CEF3 http opensource spotify com cefbuilds index html 2 下载CMake xff0c 运行CMake GUI exe 3 CMake