• Chromium Embedded Framework


    关于CEF

    近期由于工作需要开始研究了Google的Chromium Embedded Framework(CEF),这是一个基于Google Chromium开源代码的项目,使用CEF可以很方便的在你自己程序中显示Web。简单的调研后发现,现在很多主流的客户端都使用了CEF来显示Web页面:网易云音乐、QQ、豌豆荚等(安装目录下可以找到libcef.dll)。

    下载CEF

    我使用的是3.1650.1562版本,CEF的发布版本在这里下载http://www.magpcss.net/cef_downloads/,页面下方的Download List表格中列出的是最新的发布版本(包括Windows、Linux、MacOS平台的32、64位版本)。我下载的是cef_binary_3.1650.1562_windows32,如果表格中的版本不是3.1650.1562,可以点击 older (deprecated) versions去找到。下载到本地之后解压缩到本地文件夹(我解压到了D:cef_binary_3.1650.1562_windows32),打开文件夹后使用VS2010开打cefclient2010.sln,可以看到两个项目:cefclient、libcef_dll_wrapper。编译Debug版本的cefclient项目,确保可以编译通过,此时会在out目录下(我的目录是D:cef_binary_3.1650.1562_windows32outDebug)生成相应的文件,运行cefclient.exe会显示出Google的页面。cefclient是如何使用cef的一个例子,具体可以参考项目代码。

    将CEF嵌入到单文档程序中

    在VS2010中,点击菜单项文件-》新建-》项目,选择MFC应用程序,项目名称命名为:CEFBrowser,项目位置根据你上面的解压缩位置而定,我的是D:cef_binary_3.1650.1562_windows32,解决方案选择“添加到解决方案”,点击“确定”。如下图所示:
     
     
    在“应用程序类型”中选择“单个文档”,MFC的使用选择“在静态库中使用MFC”,其余的选项默认,点击“完成”。可以看到在解决方案中新添加了CEFBrowser项目。
     
     
     
     
    首先,将CEFBrowser项目设置为启动项目。右键点击CEFBrowser打开项目的“属性页”,点击“通用属性”-》框架和引用-》添加新引用,在弹出的“添加引用”对话框中选择“libcef_dll_wrapper”项目,点击“确定”。如下图所示:
     


     
    点击“确定”退出属性页。libcef_dll_wrapper生成静态库libcef_dll_wrapper.lib,输出到cef_binary_3.1650.1562_windows32outDebuglib目
    录下,我们的程序需要加载这个静态库,当然你也可以在设置中按照目录包含它,或者在程序中使用#pragma comment链接它。
     
    然后,在“配置属性”-》C/C++-》常规-》附加包含目录,加入../,因为我们的程序需要inlclude文件夹下的头文件,include目录位于上一级目录。
     
     
    其次,将cefclient项目属性页中的链接器-》常规-》附加库目录的内容全部拷贝到CEFBrowser项目的相应位置:
     
     
    最后,将cefclient属性页的输入-》附加依赖项中的内容全部拷贝到CEFBrowser项目的相应位置,并且将最后的$(Configuration)libcef.lib前面加上../改为../$(Configuration)libcef.lib
     
     
    以上工程的环境就配置好了,下面开始添加使用cef的代码:
     
    • 给CEFBrowser工程添加一个空白的头文件:ExampleCefApp.h,文件中加入如下代码:
      [cpp] view plain copy
       
      1. #pragma once  
      2. #include "include/cef_app.h"  
      3.   
      4. class ExampleCefApp : public CefApp  
      5. {  
      6. public:  
      7.     ExampleCefApp ()  
      8.     {  
      9.     }  
      10.     virtual ~ExampleCefApp ()  
      11.     {  
      12.     }  
      13.   
      14. private:  
      15.     IMPLEMENT_REFCOUNTING (ExampleCefApp);  
      16. };  
    • 在给CEFBrowser工程添加一个空白的头文件:ExampleCefHandler.h,文件中加入如下代码:
      [cpp] view plain copy
       
      1. #pragma once  
      2.   
      3. #include "include/cef_client.h"  
      4.   
      5. class ExampleCefHandler : public CefClient,  
      6.     public CefContextMenuHandler,  
      7.     public CefDisplayHandler,  
      8.     public CefDownloadHandler,  
      9.     public CefDragHandler,  
      10.     public CefGeolocationHandler,  
      11.     public CefKeyboardHandler,  
      12.     public CefLifeSpanHandler,  
      13.     public CefLoadHandler,  
      14.     public CefRequestHandler  
      15. {  
      16. public:  
      17.     ExampleCefHandler();  
      18.     virtual ~ExampleCefHandler();  
      19.     CefRefPtr<CefBrowser> GetBrowser();  
      20.   
      21. #pragma region CefClient  
      22.     // since we are letting the base implementations handle all of the heavy lifting,  
      23.     // these functions just return the this pointer  
      24.     virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler () OVERRIDE;  
      25.     virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler () OVERRIDE;  
      26.     virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler () OVERRIDE;  
      27.     virtual CefRefPtr<CefDragHandler> GetDragHandler () OVERRIDE;  
      28.     virtual CefRefPtr<CefGeolocationHandler> GetGeolocationHandler () OVERRIDE;  
      29.     virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler () OVERRIDE;  
      30.     virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler () OVERRIDE;  
      31.     virtual CefRefPtr<CefLoadHandler> GetLoadHandler () OVERRIDE;  
      32.     virtual CefRefPtr<CefRequestHandler> GetRequestHandler () OVERRIDE;  
      33. #pragma endregion // CefClient  
      34.   
      35. #pragma region CefDownloadHandler  
      36.     // this function is virtual and must be implemented; we do nothing in it, so downloading files won't work as the callback function isn't invoked  
      37.     virtual void OnBeforeDownload (CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item, const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback);  
      38. #pragma endregion // CefDownloadHandler   
      39.   
      40. #pragma region CefLifeSpanHandler  
      41.     // cache a reference to the browser  
      42.     virtual void OnAfterCreated (CefRefPtr<CefBrowser> browser) OVERRIDE;  
      43.     // release the browser reference  
      44.     virtual void OnBeforeClose (CefRefPtr<CefBrowser> browser) OVERRIDE;  
      45. #pragma endregion // CefLifeSpanHandler    
      46.   
      47. protected:  
      48.     // the browser reference  
      49.     CefRefPtr<CefBrowser> browser;  
      50.   
      51.     // Include the default reference counting implementation.  
      52.     IMPLEMENT_REFCOUNTING (ExampleCefHandler);  
      53.     // Include the default locking implementation.  
      54.     IMPLEMENT_LOCKING (ExampleCefHandler);  
      55. };  
    • 然后给CEFBrowser工程添加一个空白的源文件:ExampleCefHandler.cpp,加入代码如下:
      [cpp] view plain copy
       
      1. #include "stdafx.h"  
      2. #include "ExampleCefHandler.h"  
      3.   
      4.   
      5. ExampleCefHandler::ExampleCefHandler ()  
      6. {  
      7. }  
      8.   
      9. ExampleCefHandler::~ExampleCefHandler ()  
      10. {  
      11. }  
      12.   
      13. CefRefPtr<CefBrowser> ExampleCefHandler::GetBrowser ()  
      14. {  
      15.     return browser;  
      16. }  
      17.   
      18. CefRefPtr<CefContextMenuHandler> ExampleCefHandler::GetContextMenuHandler ()   
      19. {  
      20.     return this;  
      21. }  
      22.   
      23. CefRefPtr<CefDisplayHandler> ExampleCefHandler::GetDisplayHandler ()   
      24. {  
      25.     return this;  
      26. }  
      27.   
      28. CefRefPtr<CefDownloadHandler> ExampleCefHandler::GetDownloadHandler ()   
      29. {  
      30.     return this;  
      31. }  
      32.   
      33. CefRefPtr<CefDragHandler> ExampleCefHandler::GetDragHandler ()   
      34. {  
      35.     return this;  
      36. }  
      37.   
      38. CefRefPtr<CefGeolocationHandler> ExampleCefHandler::GetGeolocationHandler ()  
      39. {  
      40.     return this;  
      41. }  
      42.   
      43. CefRefPtr<CefKeyboardHandler> ExampleCefHandler::GetKeyboardHandler ()   
      44. {  
      45.     return this;  
      46. }  
      47.   
      48. CefRefPtr<CefLifeSpanHandler> ExampleCefHandler::GetLifeSpanHandler ()   
      49. {  
      50.     return this;  
      51. }  
      52.   
      53. CefRefPtr<CefLoadHandler> ExampleCefHandler::GetLoadHandler ()   
      54. {  
      55.     return this;  
      56. }  
      57.   
      58. CefRefPtr<CefRequestHandler> ExampleCefHandler::GetRequestHandler ()   
      59. {  
      60.     return this;  
      61. }  
      62.   
      63. void ExampleCefHandler::OnBeforeDownload (CefRefPtr<CefBrowser> browser,   
      64.     CefRefPtr<CefDownloadItem> download_item,   
      65.     const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback)  
      66. {  
      67.     UNREFERENCED_PARAMETER (browser);  
      68.     UNREFERENCED_PARAMETER (download_item);  
      69.     callback->Continue (suggested_name, true);  
      70. }  
      71.   
      72. void ExampleCefHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)   
      73. {  
      74.   
      75.     CefLifeSpanHandler::OnAfterCreated (browser);  
      76. }  
      77.   
      78. void ExampleCefHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)   
      79. {  
      80.     CefLifeSpanHandler::OnBeforeClose (browser);  
      81. }  
    • 切换到“类视图”,右键点击CCEFBrowserView-》属性,在属性对话框中给类CCEFBrowserView添加WM_CREATE的响应函数OnCreate。在CEFBrowserView.cpp文件开头处加入如下代码:
      [cpp] view plain copy
       
      1. #include "ExampleCefApp.h"  
      2. #include "ExampleCefHandler.h"  
      3.   
      4. #define INVALID_HWND (HWND)INVALID_HANDLE_VALUE  
      5.   
      6. namespace  
      7. {  
      8.     CefRefPtr<ExampleCefHandler> example_cef_handler;  
      9.     HWND application_message_window_handle = INVALID_HWND;  
      10. }  

      OnCreate函数的代码如下:
      [cpp] view plain copy
       
      1. int CCEFBrowserView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
      2. {  
      3.     if (CView::OnCreate(lpCreateStruct) == -1)  
      4.         return -1;  
      5.   
      6.     // TODO:  在此添加您专用的创建代码  
      7.     CefMainArgs main_args ( AfxGetApp()->m_hInstance );  
      8.     CefRefPtr<ExampleCefApp> app (new ExampleCefApp);  
      9.   
      10.     if (CefExecuteProcess(main_args, app.get()) == -1)  
      11.     {  
      12.         CefSettings settings;  
      13.         CefSettingsTraits::init( &settings);  
      14.         settings.multi_threaded_message_loop = true;  
      15.         CefInitialize (main_args, settings, app.get());  
      16.   
      17.         example_cef_handler = new ExampleCefHandler();  
      18.   
      19.         CefWindowInfo info;  
      20.         info.SetAsChild(m_hWnd, CRect(0, 0, 1200, 1200));  
      21.   
      22.         CefBrowserSettings settings1;  
      23.         CefBrowserHost::CreateBrowser(info, example_cef_handler.get(), CefString ("http://www.sina.com"), setting1, NULL);  
      24.     }  
      25.     return 0;  
      26. }  


    至此,所添加的代码完毕,好了现在编译工程CEFBrowser,在Debug目录

    (我的路径是D:cef_binary_3.1650.1562_windows32Debug)中确认生成了CEFBrowser.exe,

    同时编译器自动的将需要的一些CEF文件也拷贝到了此文件夹下。此时还不能成功运行CEFBrowser.exe

    显示出页面,需要将上面我们编译cefclient项目产生的locales文件夹和cef.pak文件

    (D:cef_binary_3.1650.1562_windows32outDebug目录中)拷贝到Debug目录下

    (提示是否替换,选择是),好了现在可以运行CEFBrowser.exe显示出新浪的页面了(结果如下图)。


  • 相关阅读:
    第十七讲:解释器模式
    第十六讲:适配器模式
    第十五讲:桥接模式
    第十四讲:组合模式
    第十三讲:外观模式
    第十二讲:代理模式
    第十一讲:享元模式
    第九讲:策略模式
    工厂模式
    观察者设计模式
  • 原文地址:https://www.cnblogs.com/ouyangping/p/7685083.html
Copyright © 2020-2023  润新知