VS2019 MFC中使用CEF

本文详细介绍了如何在Visual Studio 2019的MFC项目中集成Chromium Embedded Framework (CEF),包括软件环境设置、CEF版本选择、CMake工具使用、工程配置及编译流程。此外,还提供了关键代码片段,如初始化、浏览器窗口创建、大小调整及退出过程。

VS2019 MFC中使用CEF

Chromium Embedded Framework (CEF)是基于Google Chromium项目的开源Web browser控件,支持Windows, Linux, Mac平台。
软件环境:
Windows 10家庭版
Visual Studio 2019
CEF 83.3.11+g1fac1e5+chromium-83.0.4103.61 / Chromium 83.0.4103.61,这个版本的Debug与VS2017有些不兼容,只能使用Release方式编译。但在VS2019中均可编译通过。
“D:\MyProjectsVS.1\cef_binary_83.3.11\”为CEF工程目录

下载(http://opensource.spotify.com/cefbuilds/index.html#windows32_builds
cef_binary_83.3.11+g1fac1e5+chromium-83.0.4103.61_windows32.tar.bz2
如果需要调试信息,则还需要下载:(具体用法自行查找)
cef_binary_83.3.11+g1fac1e5+chromium-83.0.4103.61_windows32_debug_symbols.tar.bz2
我使用的是32位版的

解压后使用CMake工具生成VS2019的工程,步骤如下:

  1. 选择好源和目的文件夹
  2. 配置生成器为Visual Studio 16 2019
  3. 生成目标环境
  4. 使用VS2019打开工程

在这里插入图片描述
在这里插入图片描述
编译工程,注意选择Win32平台Debug方式,完成后获得以下三个文件:
D:\MyProjectsVS.1\cef_binary_83.3.11\Debug\ libcef.lib
D:\MyProjectsVS.1\cef_binary_83.3.11\Debug\ libcef.dll
D:\MyProjectsVS.1\cef_binary_83.3.11\libcef_dll_wrapper\Debug\libcef_dll_wrapper.lib

由于CEF是多进程内嵌,所以需要两个类class SimpleApp和class SimpleHandler,其中SimpleApp是用于在用户程序中创建内嵌CEF应用,而SimpleHandler是负责传递各种消息,这些消息是以虚函数的形式显现出来。SimpleHandler是继承于多个处理类,每增加一个处理类需要调用该类的GetDisplayHandler函数取得句柄,然后调用各种消息处理函数。

导入自己的工程需要四个文件(可改名),其中的产生的CefBrowser指针需由自己管理,官方例子中使用了std::list类型保存多个实例。
simple_app.cc
simple_app.h
simple_handler.cc
simple_handler.h
另外还要将D:\MyProjectsVS.1\cef_binary_83.3.11\include目录复制到自己的工程。

在应用程序的CMyApp::InitInstance()中添加初始化代码:

CefMainArgs main_args(m_hInstance);  
CefRefPtr<SimpleApp> app(new SimpleApp);
int exit_code = CefExecuteProcess(main_args, app.get(), NULL);
if (exit_code >= 0)
{
	exit(exit_code);
}
CefSettings settings;
CefSettingsTraits::init(&settings);
settings.no_sandbox = true;
settings.multi_threaded_message_loop = true;
CefInitialize(main_args, settings, app.get(), NULL);

在相应的CWebView::OnCreate(LPCREATESTRUCT lpCreateStruct)中生成浏览器窗口

CefWindowInfo info;  
CefBrowserSettings settings;  
cef32_handler = new SimpleHandler(true);

info.SetAsChild(m_hWnd, CRect(0, 0, 1000, 1000));  
CefBrowserHost::CreateBrowser(info, cef32_handler, CefString("about:blank"), settings, nullptr, nullptr);

在CWebView::OnSize(UINT nType, int cx, int cy)中控制大小适应窗口

if(cef32_handler.get() && cx > 0 && cy > 0)
	{
		CefRefPtr<CefBrowser>browser = cef32_handler->GetBrowser();
		if(browser)
		{
			CefWindowHandle hWnd = browser->GetHost()->GetWindowHandle();
			if(::IsWindow(m_hWnd)) ::MoveWindow(hWnd, 0, 0, cx, cy, true); 
		}
	}

在CMyApp::ExitInstance()中退出CEF

	CefQuitMessageLoop();
	CefShutdown();

Debug版本使用CefShutdown()会在debug.log中产生错误报告,Release发行版会忽略。

运行时所需的文件如下:

文件名类型说明
localesfolder本地化资源。CefSettings.locale指定需要加载的pak文件,只需要发布配置的区域对应的pak文件
cef.pakfile这些文件包含了供CEF使用的区域无关资源,缺少这些文件任意Web组件可能显示不正确
cef_100_percent.pakfile同上
cef_200_percent.pakfile同上
cef_extensions.pakfile此文件包含扩展加载所需的非本地化资源传递--disable-extensions命令行标志来禁止使用文件。没有这个文件,依赖于扩展系统的组件将不起作用, 如PDF查看器
chrome_elf.dllfileCrash reporting library,崩溃报告
d3dcompiler_43.dll 或 d3dcompiler_47.dllfileWindows XP/Vista和更高版本的系统需要该文件
devtools_resources.pakfile此文件包含Chrome开发者工具所需的非本地化资源,缺少这个文件,Chrome开发者工具将无法运行
icudtl.datfile用来支持unicode,缺少这些文件虽然编译能通过,但是执行CefInitialize();的时候就会崩溃
libcef.dllfile核心库,要区分Debug和Release
libEGL.dllfileDirect3D支持文件,如果缺少这些文件,HTML5在渲染2D画布,3D CSS,WebGL时将不起作用
libGLESv2.dllfile同上
snapshot_blob.binfileV8引擎快照数据
v8_context_snapshot.binfile同上

注:V8引擎是一种JavaScript运行引擎,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。

### 在MFC中集成CEF137的使用方法 在MFC(Microsoft Foundation Classes)中集成CEF(Chromium Embedded Framework)版本137需要完成一系列配置和编码工作。以下是详细的说明,涵盖从环境准备到代码实现的过程[^1]。 #### 1. 环境准备 在开始之前,确保已安装以下工具和库: - Visual Studio:建议使用2019或更高版本。 - CEF SDK:下载并解压CEF 137版本的SDK至指定目录。 - MFC支持:确保Visual Studio中启用了对MFC的支持。 #### 2. 配置项目 将CEF库添加到MFC项目的依赖项中: - 将CEF的`include`目录添加到项目的“附加包含目录”中。 - 将CEF的`lib`目录添加到项目的“附加库目录”中。 - 在链接器设置中添加CEF的静态库文件(如`cef.lib`)。 #### 3. 初始化CEFMFC应用程序的初始化阶段调用CEF的初始化函数。通常在`CWinApp::InitInstance()`中完成此操作: ```cpp #include "include/cef_app.h" #include "include/cef_client.h" BOOL CYourMfcApp::InitInstance() { // 初始化CEF CefMainArgs main_args(::GetModuleHandle(NULL)); CefSettings settings; CefInitialize(main_args, settings, NULL, NULL); // 其他初始化代码... return TRUE; } ``` #### 4. 创建浏览器窗口 在MFC窗口类中创建一个CEF浏览器实例。可以通过重载`OnCreate()`或其他适当的事件处理函数来完成: ```cpp #include "include/cef_browser.h" #include "include/cef_client.h" void CYourMfcDialog::CreateBrowser() { RECT rect; GetClientRect(&rect); CefWindowInfo window_info; window_info.SetAsChild(m_hWnd, rect); CefBrowserSettings browser_settings; CefRefPtr<CefClient> client; // 可以自定义实现 CefBrowserHost::CreateBrowser(window_info, client, "https://www.example.com", browser_settings, nullptr, nullptr); } ``` #### 5. 清理资源 在应用程序退出时清理CEF资源,防止内存泄漏: ```cpp int CYourMfcApp::ExitInstance() { CefShutdown(); return CWinApp::ExitInstance(); } ``` #### 6. 处理消息循环 为了确保CEF的消息循环与MFC的消息循环同步,需在主消息循环中调用CEF的消息处理函数: ```cpp BOOL CYourMfcApp::PreTranslateMessage(MSG* pMsg) { CefDoMessageLoopWork(); return CWinApp::PreTranslateMessage(pMsg); } ``` --- ### 示例代码 以下是一个完整的示例,展示如何在MFC对话框应用程序中集成CEF: ```cpp // YourMfcApp.cpp #include "stdafx.h" #include "YourMfcApp.h" #include "include/cef_app.h" BOOL CYourMfcApp::InitInstance() { CefMainArgs main_args(::GetModuleHandle(NULL)); CefSettings settings; CefInitialize(main_args, settings, NULL, NULL); CYourMfcDialog dlg; m_pMainWnd = &dlg; dlg.DoModal(); CefShutdown(); return FALSE; } // YourMfcDialog.cpp #include "stdafx.h" #include "YourMfcDialog.h" #include "include/cef_browser.h" #include "include/cef_client.h" void CYourMfcDialog::CreateBrowser() { RECT rect; GetClientRect(&rect); CefWindowInfo window_info; window_info.SetAsChild(m_hWnd, rect); CefBrowserSettings browser_settings; CefRefPtr<CefClient> client; // 自定义实现 CefBrowserHost::CreateBrowser(window_info, client, "https://www.example.com", browser_settings, nullptr, nullptr); } BOOL CYourMfcApp::PreTranslateMessage(MSG* pMsg) { CefDoMessageLoopWork(); return CWinApp::PreTranslateMessage(pMsg); } ``` --- ### 注意事项 - 确保CEF的动态链接库(如`cef.dll`)与应用程序在同一目录下。 - 如果需要自定义客户端行为,可以继承`CefClient`并实现相关接口[^2]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值