在mfc中使用cef实现webkit的浏览器
转载自 heycode
首先,下载一个cef的开发包,我下载的是 cef_binary_3.2171.1901_windows32 这个版本的(下载链接)。
下载完成解压后,用vs打开,编译其中的 libcef_dll_wrapper 这个项目。编译成功后,在\out\Debug\lib 这个目录里会生成一个文件:libcef_dll_wrapper.lib,这个文件在开发我们项目的时候会使用。
接下来开始创建我们的项目了。
1、打开VS,新建一个mfc的工程,应用程序类型选择“基于对话框”


2、将默认生成的对话框里面的控件全部删除

3、从cef_binary_3.2171.1901_windows32中复制一些必要的文件到我们的项目
“Release”、“Resources”这两个目录下的所有文件复制到我们项目的Debug目录下(没有Debug目录?生成一下我们的项目就会有了)

“include”这个目录,“\out\Debug\lib\libcef_dll_wrapper.lib”、“\debug\libcef.lib”这两个文件复制到源代码的目录下,如下图所示

这个项目中,我们将参考cef_binary_3.2171.1901_windows32里面提供的cefsimple这个示例来制作。为了方便,我们再复制一些cefsimple里面的代码到我们的项目里,如下图

在vs中将这些文件包含进来

如此,准备工作完成了,接下来将开始修改我们的项目了
修改项目属性
配置属性-》MFC的使用 设置为"在静态库中使用MFC"

VC++目录 包含目录 添加 include 这个目录

C/C++ => 预编译头 => 不使用编译头

代码生成 => 运行库 => 多线程调试 (/MTd)

链接器 => 输入 => 附加依赖项 添加 libcef.lib libcef_dll_wrapper.lib 这两个文件

完成代码
前面,我们添加了一些cefsimple这个示例项目的代码到我们项目中。当然,这些代码需要修改一下,首先是#include 部分

include 的路径需要调整一下,这里是删除"cefsimple/"。修改完#include后,编译一下,应该能够通过。
接下来,参考一下cefsimple里面“cefsimple_win.cpp”这个文件的代码,这里面的代码是初始化cef的
然后添加类似的代码到我们项目中
在我们项目的“MFCCef.cpp”这里面的构造函数中,添加如下代码
void* sandbox_info = NULL;
CefMainArgs main_args(AfxGetApp()->m_hInstance);
CefRefPtr<SimpleApp> app(new SimpleApp);
CefSettings settings;
settings.no_sandbox = true;
settings.multi_threaded_message_loop=true;
CefInitialize(main_args, settings, app.get(), sandbox_info);
如图:

将“simple_app.cpp”这个文件中的 void SimpleApp::OnContextInitialized() 这个方法里面的语句删除(这里面是创建窗口的方法,需要移到别的地方去)

在“MFCCefDlg.cpp”这个文件的OnInitDialog方法中,添加如下代码
CefWindowInfo window_info;
CRect rt;
GetWindowRect(&rt);
window_info.SetAsChild(this->GetSafeHwnd(), rt);
CefRefPtr<SimpleHandler> handler(new SimpleHandler());
CefBrowserSettings browser_settings;
std::string url;
url = "http://www.heycode.com";
CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL);

同时添加这个类的析构函数,以便在程序关闭时,也关闭cef
方法体内容 CefShutdown();

注意:不要忘了添加头相应的文件哦
MFCCefDlg.cpp这里需要添加的头文件
#include "simple_handler.h"
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/wrapper/cef_helpers.h"
#include "simple_app.h"
MFCCef.cpp 需要添加的头文件
#include "simple_app.h"
#include "include/cef_sandbox_win.h"
运行一下,应该就能看到效果了

自动调整大小
前面的几节我们已经将浏览器显示出来了。在测试中,我们发现了一个问题,就是调整窗口大小的时候,浏览器不会跟着变化大小。
需要怎么处理呢?其实很简单,跟其他的控件调整大小一样。添加一个WM_SIZE的消息处理

代码如下:
void CMFCCefDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
CWnd* cefwindow= FindWindowEx(this->GetSafeHwnd(),NULL,L"CefBrowserWindow",NULL);
cefwindow->MoveWindow(0,0,cx,cy);
}