CEF:MFC 对话框 Demo(VS2013)

  随着 HTML5 的崛起和 IE 的淘汰,微软 Web Browser 控件越来越不合时宜,CEF (Chromium Embedded Framework) 越来越受欢迎。但 CEF 使用起来比 Web Browser 复杂的多,而且它的官方例子 cefsimple 和 cefclient 都是使用 Win32 API 开发的,这给大家学习使用 CEF 带来了很大不便,很多人更需要一个使用 MFC 开发的例子。

  • CEF 版本:cef_binary_3.2623.1395.g3034273_windows32
  • 开发工具:Visual Studio 2013

下载 CEF

  获得 CEF 有两种方法,一种是下载源码自己编译,另一种是直接下载编译好的二进制文件。自己编译 CEF 源码太麻烦了,可谓困难重重,有兴趣的同学可以看这里:BranchesAndBuilding
  毫不犹豫的放弃自己编译的念头后,就只剩第二种方法了。网上常见的下载 CEF Binary 的地方是 http://cefbuilds.comhttp://opensource.spotify.com/cefbuilds/index.html,但这两个地方现在都连不上了。最后只好求助 CSDN:
  cef_binary_3.2623.1395.g3034273_windows32.part1
  cef_binary_3.2623.1395.g3034273_windows32.part2

编译 libcef_dll_wrapper

  libcef.dll 提供的是 C 接口。我们既然都已经使用 MFC 了,当然更想用 C++ 接口,不幸的是,这需要自己编译。编译方法如下:
  首先,下载一个 CMake,下载地址在这里:cmake-3.8.2-win32-x86.msi
  下载之后安装,安装之后运行 CMake (cmake-gui)。
  把刚才下载的 cef_binary_3.2623.1395.g3034273_windows32 解压到 D: 盘根目录。
  在 CMake 界面上分别点击 [Browse Source…] 和 [Browse Build…] 按钮,选择刚才解压 CEF 的目录,如下图:
  这里写图片描述
  再点击 [Generate] 按钮,在弹出的窗口上选择“Visual Studio 12 2013”,如下图:
  这里写图片描述
  然后点击窗口下面的 [Finish] 按钮,生成 VS2013 解决方案。
  等待一小会儿,生成完毕后的窗口如下所示,在窗口底部显示出了“Generating done”字样。
  这里写图片描述
  这时,在 D:\cef_binary_3.2623.1395.g3034273_windows32 文件夹里生成了 cef.sln 文件。
  启动 Visual Studio 2013,打开刚才生成的 cef.sln 文件。打开 cef.sln 后的 VS2013 界面如下图:
  这里写图片描述
  在“解决方案资源管理器”里,在“libcef_dll_wrapper”项目上点击鼠标右键,然后在弹出菜单上点击“生成(U)”项,编译生成 libcef_dll_wrapper。
  等一会儿后(等待时间长短依电脑性能而不同),就生成了 Debug 版的 libcef_dll_wrapper.lib。
  然后,在工具栏里,把“解决方案配置”改为“Release”,再在“libcef_dll_wrapper”项目上点击鼠标右键,在弹出菜单上点击“生成(U)”项,编译生成 Release 版的 libcef_dll_wrapper。
  最后,生成的 Debug 版和 Release 版的 libcef_dll_wrapper 分别位于 D:\cef_binary_3.2623.1395.g3034273_windows32\libcef_dll\Debug\libcef_dll_wrapper.libD:\cef_binary_3.2623.1395.g3034273_windows32\libcef_dll\Release\libcef_dll_wrapper.lib
  至此,准备工作就已经完成了。

创建 MFC 对话框项目

  关闭刚才的 Visual Studio 2013,再重新启动一个 Visual Studio 2013。
  点击菜单 [文件(F)->新建(N)->项目(P)…],打开“新建项目”对话框,在左侧选择 [已安装->模板->Visual C++->MFC],然后选择中间的“MFC 应用程序”,项目名称输入 CefMfcDemo,位置选择 D:\,如下图:
  这里写图片描述
  点击 [确定] 按钮,进入 MFC 应用程序向导,再点击 [下一步] 按钮,进入“应用程序类型”选择界面。选择“基于对话框”和“在静态库中使用 MFC”,如下图:
  这里写图片描述
  点击 [下一步],进入“用户界面功能”选择页,选择项目如下图:
  这里写图片描述
  点击 [下一步],进入“高级功能”界面,只选择“公共控件清单”就好,如下图:
  这里写图片描述
  点击 [下一步],进入“生成的类”界面,这里面不需要改什么,直接点击 [完成] 按钮,生成 CefMfcDemo 项目。
  生成项目后,对话框界面编辑器会自动打开,如下图:
  这里写图片描述
  把界面上的“TODO: ”标签、“确定”、“取消”按钮都删掉。(删完之后记得保存)

修改项目属性

  在“解决方案资源管理器”里,在项目名称“CefMfcDemo”上点击鼠标右键,然后在弹出菜单上点击“属性(R)”项,打开“CefMfcDemo 属性页”窗口。改变“配置”为“所有配置”,选择 [配置属性->VC++ 目录],把 D:\cef_binary_3.2623.1395.g3034273_windows32 添加到“包含目录”,然后点击 [确定] 按钮关闭窗口。
  这里写图片描述
  重新打开属性页窗口,改变“配置”为“Debug”,选择 [配置属性->VC++ 目录],把 D:\cef_binary_3.2623.1395.g3034273_windows32\Debug 添加到“库目录”,然后点击 [确定] 按钮关闭窗口。
  这里写图片描述
  重新打开属性页窗口,改变“配置”为“Release”,选择 [配置属性->VC++ 目录],把 D:\cef_binary_3.2623.1395.g3034273_windows32\Release 添加到“库目录”,然后点击 [确定] 按钮关闭窗口。
  这里写图片描述
  重新打开属性页窗口,改变“配置”为“所有配置”,选择 [配置属性->C/C++->预编译头],将“预编译头”改为“不使用预编译头”,然后点击 [确定] 按钮关闭窗口。
  这里写图片描述
  重新打开属性页窗口,改变“配置”为“所有配置”,选择 [配置属性->链接器->输入],把 libcef.liblibcef_dll_wrapper.lib 添加到“附加依赖项”,然后点击 [确定] 按钮关闭窗口。
  这里写图片描述

添加 CefClient 派生类

  在“解决方案资源管理器”里,在项目名称“CefMfcDemo”上点击鼠标右键,然后在弹出菜单上选择“添加(D)->类(C)…”项,打开“添加类”窗口,在左侧选择“已安装->Visual C++ ->C++”,再选择中间的“C++ 类”,然后点击 [添加(A)] 按钮,进入“一般 C++ 类向导”窗口。在“类名(L)”里输入 CSimpleClient,然后点击 [完成] 按钮,生成 CSimpleClient 类。
  这里写图片描述
  修改 SimpleClient.h 文件内容如下:

#pragma once

#include "include/cef_client.h"

class CSimpleClient : public CefClient, public CefLifeSpanHandler
{
public:
    CSimpleClient();
    ~CSimpleClient();

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

    // CefLifeSpanHandler methods:
    virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;

    CefRefPtr<CefBrowser> GetBrowser() { return m_cefBrowser; }

private:
    CefRefPtr<CefBrowser> m_cefBrowser;

    IMPLEMENT_REFCOUNTING(CSimpleClient);
};

  在 SimpleClient.cpp 文件里添加如下函数:

void CSimpleClient::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
    m_cefBrowser = browser;
}

修改 CCefMfcDemoDlg 类,创建浏览器

  首先打开 CefMfcDemoDlg.h 文件,在 #pragma once 下面添加 #include "SimpleClient.h"。然后再添加 public 成员变量:CefRefPtr<CSimpleClient> m_simpleClient;
  接着打开 CefMfcDemoDlg.cpp 文件,先在顶部添加 #include "include/cef_app.h",再在 OnInitDialog() 函数里添加如下代码:

    CefRefPtr<CSimpleClient> client(new CSimpleClient());
    m_simpleClient = client;

    CefSettings settings;
    CefSettingsTraits::init(&settings);
    settings.multi_threaded_message_loop = true;

    CefMainArgs mainArgs;
    CefRefPtr<CefApp> cefApp;
    CefInitialize(mainArgs, settings, cefApp, NULL);

    RECT rect;
    GetClientRect(&rect);
    RECT rectnew = rect;
    rectnew.top = rect.top + 50;
    rectnew.bottom = rect.bottom;
    rectnew.left = rect.left;
    rectnew.right = rect.right;

    CefWindowInfo winInfo;
    winInfo.SetAsChild(GetSafeHwnd(), rectnew);

    CefBrowserSettings browserSettings;
    CefBrowserHost::CreateBrowser(winInfo, client, _T("http://www.baidu.com"), browserSettings, NULL);

处理对话框的 WM_CLOSE 消息,关闭浏览器

  点击菜单 [视图(V)->类视图(A)],打开“类视图”窗口,展开“CefMfcDemo”节点,在类 CCefMfcDemoDlg 上点击鼠标右键,然后在弹出菜单上点击“属性(R)”项,打开“属性”窗口。在“属性”窗口工具栏上,点击“消息”图标,切换到对话框消息界面。选中 WM_CLOSE 消息,点击右侧箭头打开下拉框,点击 <add> OnClose 添加 WM_CLOSE 消息处理函数。然后光标会自动定位到刚添加的 OnClose() 函数上,在函数里添加 CefShutdown();
  这里写图片描述
  至此,在 MFC 对话框里嵌入 CEF 所需的代码就基本完成了。

编译程序

  点击菜单 [调试(D)->开始执行(不调试)(H)],编译并运行程序,这时会出现错误信息 无法打开文件“libcef_dll_wrapper.lib”,其实这个文件我们在第二步早已经生成了。
  把 D:\cef_binary_3.2623.1395.g3034273_windows32\libcef_dll\Debug\libcef_dll_wrapper.lib 复制到 D:\cef_binary_3.2623.1395.g3034273_windows32\Debug 下面,把 D:\cef_binary_3.2623.1395.g3034273_windows32\libcef_dll\Release\libcef_dll_wrapper.lib 复制到 D:\cef_binary_3.2623.1395.g3034273_windows32\Release 下面,然后再次点击 [调试(D)->开始执行(不调试)(H)],这次不会出现找不到 libcef_dll_wrapper.lib 文件的错误了,但又出现了新的错误,如下图:
  这里写图片描述
  实际到这一步,程序已经编译成功了,只是还缺少一些文件无法运行。

运行程序

  • D:\cef_binary_3.2623.1395.g3034273_windows32\Debug 里的所有文件(*.lib 文件除外)复制到 D:\CefMfcDemo\Debug 下面;
  • D:\cef_binary_3.2623.1395.g3034273_windows32\Release 里的所有文件(*.lib 文件除外)复制到 D:\CefMfcDemo\Release 下面;
  • D:\cef_binary_3.2623.1395.g3034273_windows32\Resources 里面的所有子文件夹及文件全部复制到 D:\CefMfcDemo\Debug 下面;
  • D:\cef_binary_3.2623.1395.g3034273_windows32\Resources 里面的所有子文件夹及文件全部复制到 D:\CefMfcDemo\Release 下面。
      然后再次点击 [调试(D)->开始执行(不调试)(H)],程序运行如下图:
      这里写图片描述
      至此,就实现了一个完整的使用 MFC 开发的 CEF 程序。

  可是这个程序有点儿太粗糙了,对于完美主义者是无法接受的。好吧,就再多做点儿吧。

处理 WM_SIZE 消息

  像添加 WM_CLOSE 消息处理函数一样,添加 WM_SIZE 消息处理函数 OnSize()。然后在 OnSize() 函数里添加如下代码:

    RECT rect;
    GetClientRect(&rect);

    if (m_simpleClient.get())
    {
        CefRefPtr<CefBrowser> browser = m_simpleClient->GetBrowser();
        if (browser)
        {
            CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
            ::MoveWindow(hwnd, 0, 50, rect.right - rect.left, rect.bottom - 50, true);
        }
    }

添加网址输入框

  点击菜单 [视图(V)->其他窗口(E)->资源视图(R)],打开“资源视图”窗口,依次展开“CefMfcDemo->CefMfcDemo.rc->Dialog”节点,双击 IDD_CEFMFCDEMO_DIALOG,打开对话框界面编辑窗口。
  在对话框顶部添加一个 Edit Control 和一个 Button,修改 Edit Control 的 ID 为 IDC_EDIT_URL,修改 Button 的 ID 为 IDC_BTN_GO,修改 Button 的 Caption 为 Go,完成后的界面如下图:
  这里写图片描述
  在 Go 按钮上点击鼠标右键,然后在弹出菜单上点击“添加事件处理程序(A)…”项,打开“事件处理程序向导”窗口。
  这里写图片描述
  不做任何改动,直接点击 [添加编辑(A)] 按钮,然后光标会自动定位到刚添加的 OnBnClickedBtnGo() 函数上,在函数里添加如下代码:

    CString strUrl;
    GetDlgItem(IDC_EDIT_URL)->GetWindowText(strUrl);
    if (strUrl.Trim().IsEmpty())
    {
        AfxMessageBox(_T("请输入网址"));
        return;
    }
    const CefString cefStrUrl(strUrl);
    m_simpleClient->GetBrowser()->GetMainFrame()->LoadURL(cefStrUrl);

  好了,运行程序吧,PERFECT!
  
参考:MFC对话框应用程序中谷歌CEF浏览器内核的使用
   关于MFC中如何使用CEF内核
   cefsimple 源码

源码下载:http://download.csdn.net/download/blackwoodcliff/9898152

  • 10
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
很抱歉,我没有现成的 CEF3 集成 MFC 多文档的 demo。不过,下面是一个简单的示例,可以帮助你了解如何将 CEF3 集成到 MFC 多文档应用程序中。 1. 下载 CEF3 的最新版本,并解压到本地。 2. 在 MFC 应用程序中添加一个 WebBrowser 控件(可以通过“工具箱”中的“WebBrowser”工具添加)。 3. 在 WebBrowser 控件的创建事件中,创建一个 CefBrowser 对象,并将其绑定到 WebBrowser 控件上。示例代码如下: ```c++ // 在 MFC 应用程序的某个类中添加以下代码: CefRefPtr<CefBrowser> m_pBrowser; // 声明 CefBrowser 对象 // 在 WebBrowser 控件的创建事件中添加以下代码: CefMainArgs mainArgs; // CEF 的主要参数 CefRefPtr<CefApp> app; // CEF 应用程序对象(自定义) CefSettings settings; // CEF 的设置选项 CefInitialize(mainArgs, settings, app); // 初始化 CEF CefWindowInfo windowInfo; // CEF 窗口信息 windowInfo.SetAsChild(m_hWnd, rect); // 将 CEF 窗口绑定到 WebBrowser 控件 CefBrowserSettings browserSettings; // CEF 浏览器设置 m_pBrowser = CefBrowserHost::CreateBrowserSync(windowInfo, handler.get(), url, browserSettings, nullptr); // 创建 CefBrowser 对象,并绑定到 WebBrowser 控件 ``` 4. 在 MFC 应用程序中添加一个自定义文档类(比如 CMyHtmlDoc),用于加载和显示 HTML 页面。 5. 在 CMyHtmlDoc 的 OnNewDocument() 函数中,创建一个 CefFrame 对象,将其绑定到 CefBrowser 对象上,然后使用 CefFrame::LoadURL() 函数加载 HTML 页面。示例代码如下: ```c++ // CMyHtmlDoc::OnNewDocument() 函数 CefRefPtr<CefFrame> frame = m_pBrowser->GetMainFrame(); // 获取 CefBrowser 的主框架 frame->LoadURL(url); // 加载 HTML 页面 ``` 6. 在 CMyHtmlDoc 的 OnDraw() 函数中,使用 CefBrowser::GetImage() 函数获取 HTML 页面的截图,并在文档视图中显示。示例代码如下: ```c++ // CMyHtmlDoc::OnDraw() 函数 CefRefPtr<CefBrowser> browser = GetBrowser(); // 获取 CefBrowser 对象 CefRefPtr<CefBrowserHost> host = browser->GetHost(); // 获取 CefBrowserHost 对象 CefRect rect(0, 0, host->GetWindowHandle(), host->GetWindowHandle()); // 截图区域 CefRefPtr<CefBrowser> image = host->GetImage(PET_VIEW, 1, rect); // 获取截图 CefRefPtr<CefImage> cefImage = image->GetImage(); // 获取 CefImage 对象 HBITMAP hBitmap = cefImage->GetHBITMAP(1.0, false, false); // 将 CefImage 转换为 HBITMAP CDC* pDC = GetDC(); // 获取文档视图的设备上下文 CBitmap bitmap; bitmap.Attach(hBitmap); CBrush brush; brush.CreatePatternBrush(&bitmap); pDC->FillRect(&m_rectDraw, &brush); // 在文档视图中显示截图 ReleaseDC(pDC); ``` 以上代码仅供参考,具体实现细节可能因应用程序的需求而有所不同。希望这些信息对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值