使用CEF(2)— 基于VS2019编写一个简单CEF样例
在这一节中,本人将会在Windows下使用VS2019创建一个空白的C++Windows Desktop Application项目,逐步进行修改配置和代码编写,并在这个过程中介绍vs使用过程中和C++项目的结合。源码见文章末尾Github链接。
前提
你已经阅读过《使用CEF(1)— 起步》,你可以在这些地方读到:知乎链接、cnblogs。或,你知道如何获得libcef的库以及libcef_dll_wrapper静态库。
文件准备
接下来,本人将以Debug的模式下完成代码的开发工作。在Release下是同样的步骤,但是需要注意的是你所选择的目标是Debug或是Release都需要和libcef库以及libcef_dll_wrapper完全一致。
- 现在,你需要libcef库文件相关文件,它来自于:
- 你需要使用libcef_dll_wrapper静态库文件,它来自于你编译出来的静态库:
- 你需要libcef与wrapper的include文件,它来自于:
接下来我们创建一个名为cef的文件夹,并且把上述提到的文件夹和文件放到该目录下:
cef
│ libcef_dll_wrapper.lib
│ libcef_dll_wrapper.pdb
│
├─Debug
│ │ ......
│ │ libcef.dll
│ │ libcef.lib
│ │ libEGL.dll
│ │ libGLESv2.dll
│ │ ......
│ │
│ └─swiftshader
│ libEGL.dll
│ libGLESv2.dll
│
└─include
│ cef_accessibility_handler.h
│ cef_api_hash.h
│ cef_app.h
│ cef_audio_handler.h
| .....
基础文件创建完成后,我们开始编写一个简单的基于CEF的程序吧!
项目创建
创建一个Windows桌面应用程序
创建一个名为simple-cef的项目
创建完成后,我们删除所有模板生成的代码,得到一个完全空白的应用程序项目:
依赖添加
头文件添加
众所周知,C/C++头文件作为声明定义,对于编译过程有着举足轻重的位置。当我们引入CEF编译我们的项目时候,首先需要include正确位置的头文件,才能实现编译(狭义的编译,不包括链接)。我们首先把上述做好的cef文件夹放到项目所在目录下,也就是说我们把cef的inlucde头文件以及静态库文件全都加到了项目中:
然后,在VS中,我们通过如下的方式为我们的项目引入CEF的头文件:
右键项目 — properties — C/C++ — General — Additional Include Directories
PS:如果你发现没有C/C++分类,是因为你没有创建任何的源代码文件,官方FAQ。所以我们在Source Files目录下先创建一个main.cpp,然后继续上述的配置。
PS:这里本人使用了$(ProjectDir)
,它是一个VS宏变量,返回项目所在目录(即,vcxproj所在目录),且目录末尾带反斜杠。从上面的Evaluated value里面展示的经过实际计算得到的值,可以验证我们配置是否正确。这里正确的返回了我们放在项目目录下的cef文件夹。
这里只需要添加到cef文件夹这一层级,是因为cef/include里面的头文件在include的时候,采用了对应的"include/xxx.h",即需要从引入目录中找到include文件夹,里面查找xxx.h头文件。当我们指定到了cef层级后,就能够使得编译器正确处理cef头文件中include的位置。
这里以$(ProjectDir)cef/include/cef_broweser.h这个头文件举例:
当编译器发现里面的#include预编译命令后,会从头文件目录中去查找,即希望从上述配置的$(ProjectDir)cef/以及默认目录下查找,默认的项目目录应该是找不到了,但是可以在$(ProjectDir)cef/目录下找到include/cef_base.h等文件,因为$(ProjectDir)cef/include/cef_base.h确实是正确的文件路径。因此,上述额外的include文件夹只需要指定到cef层级即可。
库文件添加
完成头文件的添加后,我们还需要添加链接目标,即cef的静态库。添加方式为:
properties — Linker — Input— Additional Dependencies
同样使用宏变量来指定对应的lib静态库:libcef_dll_wrapper.lib、libcef.lib、cef_sandbox.lib。
通过上述的库文件添加,我们就完成了编译(狭义,头文件查找)——链接(库文件链接)这两个步骤的配置了,接下来就是进一步,开始我们的代码编写之路。
代码编写与说明
CEF的整体架构以及CefApp以及CefClient的概念可以参考该仓库里面的文档,或者是阅读官方文档。接下来将使用cefsimple代码进行解释说明,并适当增加一些小的细节。
simple_app
simple_app.h
#ifndef SIMPLE_APP_H
#define SIMPLE_APP_H
#pragma once
#include "include/cef_app.h"
// Implement application-level callbacks for the browser process.
class SimpleApp : public CefApp, public CefBrowserProcessHandler {
public:
SimpleApp();
// CefApp methods:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
OVERRIDE {
return this;
}
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleApp);
};