CEF版本是Branch 2171 开发环境是VS2012


查看一下libcef_dll_wrapper工程属性,确定Code Generation 选择MTD(Debug) 或者MT(Release),这个设置是编译出的静态库是多线程静态链接,在其他工程中使用时,使用者的工程属性也要对应设置MTD或者MT,让二者保持一致,这样保证不会链接出错。

然后我们选择ALL_BUILD后Build,如果不出意外应该会报编译错误:

然后上网搜了一下,是编译器把警告当成错误了

参考我之前博客可以解决:http://www.cnblogs.com/chechen/p/6104879.html

CEF运行主要依赖的库就是libcef_dll_wrapper.lib和libcef.lib,其中libcef_dll_wrapper.lib是静态库,libcef.lib 动态库。

一、在MFC中嵌入CEF浏览器窗口

1.第一步

第二步: 


第三步:

Finish之后,调整一下对话框的大小,把对话框上的按钮去掉。

第四步:

把include文件夹拷贝到当前目录

第五步:在上一级目录下新建两个目录bin和Lib

第六步:把CEF工程中Resources目录下的文件全部拷贝到bin目录下

第七步:把CEF工程中Debug下除两个.lib文件全部拷贝到bin目录下

第八步:把Debug目录下的libcef.lib文件和libcef_dll_wrapper\\Debug目录下的libcef_dll_wrapper.lib拷贝到Lib文件下

第九步:工程设置

第十步:在stdafx.h文件中加入队CEF库的引用和用到的头文件


#include "include/cef_app.h"
  #include "include/cef_client.h"

// 添加引用CEF的库
#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\libcef.lib")
# pragma comment(lib, "..\\Lib\\libcef_dll_wrapper.lib")
# else
// Release
# endif
#else
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\libcef.lib")
# pragma comment(lib, "..\\Lib\\libcef_dll_wrapper.lib")
# else
// Release
# endif
#endif

这时我编译一下,检查引用库是否正常

第十一步:实现我们自己浏览器的CefApp类

.h文件

 #ifndef _CEFBROWSERAPP_H_
#define _CEFBROWSERAPP_H_ class CCefBrowserApp :public CefApp,
public CefBrowserProcessHandler
{
public:
CCefBrowserApp(void);
~CCefBrowserApp(void); // CefApp methods:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
OVERRIDE { return this; } // CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE; private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(CCefBrowserApp);
}; #endif //_CEFBROWSERAPP_H_

.cpp文件

 #include "stdafx.h"
#include "CefBrowserApp.h" CCefBrowserApp::CCefBrowserApp(void)
{ } CCefBrowserApp::~CCefBrowserApp(void)
{ } void CCefBrowserApp::OnContextInitialized()
{ }

第十二步:按照分析的步骤编写浏览器并嵌入到我们的MFC主窗口中,在InitInstance中初始化cef

 /***************************************begin初始化cef*******************************************/

     void* sandbox_info = NULL;
CefMainArgs main_args(AfxGetApp()->m_hInstance);
CefRefPtr<CCefBrowserApp> spApp(new CCefBrowserApp); // Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, spApp.get(),sandbox_info);
if (exit_code >= )
return exit_code;
CefSettings cSettings;
cSettings.no_sandbox = true;
cSettings.multi_threaded_message_loop = true;
// Execute the secondary process, if any.
CefInitialize(main_args, cSettings, spApp.get(),sandbox_info);
/***************************************结束初始化cef*******************************************/

第十三步:在对话框OnInitDialog函数中创建浏览器,在创建前我们先实现自己的CefClient类

.h文件

 #ifndef _CEFBROWSERHANDLER_H_
#define _CEFBROWSERHANDLER_H_ #include <list> class CCefBrowserHandler: public CefClient,
public CefDisplayHandler,//显示变化事件
public CefLifeSpanHandler,//Browser生命周期
public CefLoadHandler//加载错误事件
{
public:
CCefBrowserHandler(void);
~CCefBrowserHandler(void); public:
// CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE; public:
// load handler method
virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; public:
// display handler meethod
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
public:
// own method of cef browser event handler
void CloseAllBrowser(bool bForceClose = true);
protected:
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList m_browser_list; IMPLEMENT_REFCOUNTING(CCefBrowserHandler); };
#endif //_CEFBROWSERHANDLER_H_

.cpp文件

 #include "stdafx.h"
#include "CefBrowserHandler.h"
#include <sstream>
#include <string>
#include "include/base/cef_bind.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h" CCefBrowserHandler::CCefBrowserHandler(void)
{ } CCefBrowserHandler::~CCefBrowserHandler(void)
{ } CefRefPtr<CefDisplayHandler> CCefBrowserHandler::GetDisplayHandler()
{
return this;
} CefRefPtr<CefLifeSpanHandler> CCefBrowserHandler::GetLifeSpanHandler()
{
return this;
} CefRefPtr<CefLoadHandler> CCefBrowserHandler::GetLoadHandler()
{
return this;
} void CCefBrowserHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode,
const CefString& errorText, const CefString& failedUrl)
{
CEF_REQUIRE_UI_THREAD();
if (ERR_ABORTED == errorCode)
return ; std::stringstream ss;
ss << "<html><body bgcolor=\"white\">"
"<h2>Failed to load URL " << std::string(failedUrl) <<
" with error " << std::string(errorText) << " (" << errorCode <<
").</h2></body></html>";
frame->LoadString(ss.str(), failedUrl);
} void CCefBrowserHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD();
m_browser_list.push_back(browser);
} bool CCefBrowserHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD();
if ( == m_browser_list.size())
{
}
return false;
} void CCefBrowserHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD();
for (BrowserList::iterator bit = m_browser_list.begin(); bit != m_browser_list.end(); ++bit)
{
if ((*bit)->IsSame(browser)) {
m_browser_list.erase(bit);
break;
}
} if (m_browser_list.empty())
{
CefQuitMessageLoop();
}
} void CCefBrowserHandler::CloseAllBrowser(bool force_close)
{
if (!CefCurrentlyOn(TID_UI))
{
CefPostTask(TID_UI,base::Bind(&CCefBrowserHandler::CloseAllBrowser, this, force_close));
return;
} if (m_browser_list.empty())
return; BrowserList::const_iterator it = m_browser_list.begin();
for (; it != m_browser_list.end(); ++it)
{
(*it)->GetHost()->CloseBrowser(force_close);
}
}

在OnInitDialog()函数中创建浏览器

    //开始创建浏览器
CRect rtBody; GetWindowRect(&rtBody); CefWindowInfo cefWindowInfo; cefWindowInfo.SetAsChild(GetSafeHwnd(), rtBody); CefBrowserSettings browserSetting; CefRefPtr<CCefBrowserHandler> objEventHandler(new CCefBrowserHandler()); CefBrowserHost::CreateBrowser(cefWindowInfo, objEventHandler.get(), _T("http://www.baidu.com"), browserSetting, NULL);

第十三步:关闭主窗口时,关闭浏览器

给对话框添加WM_DESTROY消息响应

void CMFCCefDemoDlg::OnDestroy()
{ CDialogEx::OnDestroy(); // TODO: Add your message handler code here CefShutdown();
}

MFCDemo转载:http://blog.csdn.net/lixiang987654321/article/details/52174121

二、在Win32窗口里嵌入CEF浏览器窗口

第一步:新建Win32项目

第二步:使用默认

第三步:修改工程属性

第四步:在stdafx.h中加入 CEF库

#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\libcef.lib")
# pragma comment(lib,"..\\Lib\\libcef_dll_wrapper.lib")
# else
# //Release
# endif
#else
# ifdef _UNICODE
# //Multi_Debug
# else
# //Multi_Release
# endif
#endif

第五步:在工程目录下新建两个目录,分别为bin和Lib

第六步:把CEF工程中Resources目录下的文件全部拷贝到bin目录下

第七步:把CEF工程中Debug下除两个.lib文件全部拷贝到bin目录下

第八步:把Debug目录下的libcef.lib文件和libcef_dll_wrapper\\Debug目录下的libcef_dll_wrapper.lib拷贝到Lib文件下

第九步:工程设置-->指定生成的exe文件的路径

第十步:实现自己的CefApp

.h

 #ifndef _MYCEFAPP_H_
#define _MYCEFAPP_H_ #include "include/cef_app.h" class CMyCefApp: public CefApp,
public CefBrowserProcessHandler { public:
CMyCefApp(void);
~CMyCefApp(void); // CefApp methods:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
OVERRIDE { return this; } // CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE; private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(CMyCefApp);
}; #endif//_MYCEFAPP_H_

.cpp

 #include "stdafx.h"
#include "MyCefApp.h" CMyCefApp::CMyCefApp(void)
{ } CMyCefApp::~CMyCefApp(void)
{ } void CMyCefApp::OnContextInitialized() { }

第十二步:实现自己的Handler类

.h

 #pragma once
#include "include/cef_client.h"
#include <list>
#include <string>
using std::wstring; class CCefHandler:
public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler
{
public:
CCefHandler(); virtual ~CCefHandler(void); // Provide access to the single global instance of this object.
static CCefHandler* GetInstance(); // CefClient methods:
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
return this;
} // CefDisplayHandler methods:
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) OVERRIDE; // CefLifeSpanHandler methods:
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE; // CefLoadHandler methods:
virtual void OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& errorText,
const CefString& failedUrl) OVERRIDE; // Request that all existing browser windows close.
//void CloseAllBrowsers(bool force_close); bool IsClosing() const { return is_closing_; } CefRefPtr<CefBrowser> GetBrowser(){return m_browser;} private:
// List of existing browser windows. Only accessed on the CEF UI thread.
//typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
// BrowserList browser_list_; CefRefPtr<CefBrowser> m_browser; bool is_closing_; // Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(CCefHandler);
}

.cpp

 #include "stdafx.h"
#include "CefHandler.h"
#include <sstream>
#include <string> #include "include/cef_app.h"
#include "include/cef_runnable.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"
namespace { CCefHandler* g_instance = NULL; } // namespace CCefHandler::CCefHandler()
: is_closing_(false)
,m_browser(NULL){ g_instance = this;
} CCefHandler::~CCefHandler() {
g_instance = NULL;
} // static
CCefHandler* CCefHandler::GetInstance() {
return g_instance;
} void CCefHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD(); // Add to the list of existing browsers.
//browser_list_.push_back(browser); m_browser = browser;
} bool CCefHandler::DoClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD(); // Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
//if (browser_list_.size() == 1)
if(m_browser)
{
// Set a flag to indicate that the window close should be allowed.
is_closing_ = true;
} // Allow the close. For windowed browsers this will result in the OS close
// event being sent.
return false;
} void CCefHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title)
{ } void CCefHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD(); // Remove from the list of existing browsers.
//BrowserList::iterator bit = browser_list_.begin();
//for (; bit != browser_list_.end(); ++bit) {
// if ((*bit)->IsSame(browser)) {
// browser_list_.erase(bit);
// break;
// }
//} //if (browser_list_.empty()) {
// // All browser windows have closed. Quit the application message loop.
// CefQuitMessageLoop();
//} if(m_browser->IsSame(browser))
m_browser = NULL;
} void CCefHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& errorText,
const CefString& failedUrl)
{
CEF_REQUIRE_UI_THREAD(); // Don't display an error for downloaded files.
if (errorCode == ERR_ABORTED)
return; // Display a load error message.
std::stringstream ss;
ss << "<html><body bgcolor=\"white\">"
"<h2>Failed to load URL " << std::string(failedUrl) <<
" with error " << std::string(errorText) << " (" << errorCode <<
").</h2></body></html>";
frame->LoadString(ss.str(), failedUrl);
}

第十二步:初始化CEF

 /***************************************begin初始化cef*******************************************/

     void* sandbox_info = NULL;
CefMainArgs main_args(hInstance);
CefRefPtr<SimpleApp> spApp(new SimpleApp); // Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, spApp.get(),sandbox_info);
if (exit_code >= )
return exit_code;
CefSettings cSettings;
cSettings.no_sandbox = true;
cSettings.multi_threaded_message_loop = true; CefInitialize(main_args, cSettings, spApp.get(),sandbox_info);
/***************************************结束初始化cef*******************************************/

第十三步:在WM_CREATE消息出创建CEF浏览器窗口

先定义一个全局的Handler对象指针

CefRefPtr<CCefHandler> g_handler;

  . . . . . . .
case WM_CREATE:
{
g_handler=new CCefHandler(); RECT rect;
::GetClientRect(hWnd, &rect);
CefWindowInfo info;
info.SetAsChild(hWnd, rect); CefBrowserSettings settings1;
CefBrowserHost::CreateBrowser(info, g_handler.get(), CefString ("http://www.baidu.com"), settings1, NULL); return ;
}
. . . . . . .

至此你运行就可以看到效果了。。。

最后关闭,我们要在WM_CLOSE消息出做处理:

    case WM_CLOSE:
if (g_handler.get() && !g_handler->IsClosing()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false); // Cancel the close.
return ;
}
}
DestroyWindow(hWnd);
// Allow the close.
break;

最后程序退出时时要关闭CEF

三、CEF嵌入到Duilib窗口中

工程配置参考前面两种

1.实现自己的APP类

.h

 #ifndef _CEFBROWSERAPP_H_
#define _CEFBROWSERAPP_H_
#include "include/cef_app.h" class CCefBrowserApp
: public CefApp
, public CefBrowserProcessHandler
{
public:
CCefBrowserApp(); virtual ~CCefBrowserApp(); public:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE { return this; }; public:
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized(); protected: IMPLEMENT_REFCOUNTING(CCefBrowserApp);
};
#endif //_CEFBROWSERAPP_H_

.cpp

 #include "CefBrowserApp.h"
#include "stdafx.h" CCefBrowserApp::CCefBrowserApp()
{
} CCefBrowserApp::~CCefBrowserApp()
{
} void CCefBrowserApp::OnContextInitialized()
{
// do nothing here, because we will create browser in my own dialog
}

2.实现自己的Handler类

.h

 #ifndef _CEFBROWSEREVENTHANDLER_H_
#define _CEFBROWSEREVENTHANDLER_H_
#include "include/cef_client.h"
#include "include/base/cef_lock.h" //线程安全 class CCefBrowserEventHandler
: public CefClient
, public CefDisplayHandler // 显示变化事件
, public CefLoadHandler // 加载错误事件
, public CefLifeSpanHandler // 声明周期事件
{
public:
CCefBrowserEventHandler(); virtual ~CCefBrowserEventHandler(); public:
// CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE; public:
// display handler method
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE; public:
// load handler method
virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; public:
// display handler meethod
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE; bool IsClosing() const { return m_bIsClosing; } CefRefPtr<CefBrowser> GetBrowser(){return m_Browser;} protected: CefRefPtr<CefBrowser> m_Browser; bool m_bIsClosing; IMPLEMENT_REFCOUNTING(CCefBrowserEventHandler);
//由于CEF采用多线程架构,有必要使用锁和闭包来保证在多不同线程安全的传递数据。IMPLEMENT_LOCKING定义提供了Lock()和Unlock()方法以及AutoLock对象来保证不同代码块同步访问
IMPLEMENT_LOCKING(CCefBrowserEventHandler);//必须包含#include "include/base/cef_lock.h"
}; #endif//_CEFBROWSEREVENTHANDLER_H_

.cpp

 #include "CefBrowserEventHandler.h"
#include "stdafx.h"
#include <sstream>
#include <string>
#include "include/cef_app.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h" CCefBrowserEventHandler::CCefBrowserEventHandler(CMainFrameWnd* pMainFrame)
:m_bIsClosing(false)
{ } CCefBrowserEventHandler::~CCefBrowserEventHandler()
{ } CefRefPtr<CefDisplayHandler> CCefBrowserEventHandler::GetDisplayHandler()
{
return this;
} CefRefPtr<CefLifeSpanHandler> CCefBrowserEventHandler::GetLifeSpanHandler()
{
return this;
} CefRefPtr<CefLoadHandler> CCefBrowserEventHandler::GetLoadHandler()
{
return this;
} void CCefBrowserEventHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
{ } void CCefBrowserEventHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode,
const CefString& errorText, const CefString& failedUrl)
{
CEF_REQUIRE_UI_THREAD();
if (ERR_ABORTED == errorCode)
return ; std::stringstream ss;
ss << "<html><body bgcolor=\"white\">"
"<h2>Failed to load URL " << std::string(failedUrl) <<
" with error " << std::string(errorText) << " (" << errorCode <<
").</h2></body></html>";
frame->LoadString(ss.str(), failedUrl);
} void CCefBrowserEventHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD(); AutoLock lock_scope(this); m_Browser = browser; } bool CCefBrowserEventHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD(); AutoLock lock_scope(this); if(m_Browser)
{
// Set a flag to indicate that the window close should be allowed.
m_bIsClosing = true;
} return false;
} void CCefBrowserEventHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
CEF_REQUIRE_UI_THREAD(); AutoLock lock_scope(this); if(m_Browser->IsSame(browser))
m_Browser = NULL;
}

3.在入口函数处初始化CEF

 // Duilib_Login.cpp : 定义应用程序的入口点。
//
#include "CefBrowserApp.h"
#include "MainFrameWnd.h" int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)
{
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("CefDemo")); HRESULT Hr = ::CoInitialize(NULL);
if (FAILED(Hr)) return ; /***************************************begin初始化cef*******************************************/ void* sandbox_info = NULL;
CefMainArgs main_args(hInstance);
CefRefPtr<CCefBrowserApp> spApp(new CCefBrowserApp); // Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, spApp.get(),sandbox_info);
if (exit_code >= )
return exit_code;
CefSettings cSettings;
cSettings.no_sandbox = true;
cSettings.multi_threaded_message_loop = true;
// Execute the secondary process, if any.
CefInitialize(main_args, cSettings, spApp.get(),sandbox_info);
/***************************************结束初始化cef*******************************************/ CMainFrameWnd* pMain = new CMainFrameWnd;
pMain->Create(NULL, _T("MainFrameWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES);
pMain->CenterWindow();
pMain->ShowWindow(TRUE); if (!cSettings.multi_threaded_message_loop) {
// Run the CEF message loop. This function will block until the application
// recieves a WM_QUIT message.
CefRunMessageLoop();
}
else {
DuiLib::CPaintManagerUI::MessageLoop();
} CefShutdown(); delete pMain;
::CoUninitialize();
return ;
}

4.在CMainFrameWnd窗口类中定义一个Handler的成员变量

.........

private:
CefRefPtr<CCefBrowserEventHandler> m_handler;

在CMainFrameWnd初始化列表中构造Handler对象

CMainFrameWnd::CMainFrameWnd()
:m_handler(new CCefBrowserEventHandler())
{ }

5.在虚函数InitWindow()中创建CEF浏览器

void CMainFrameWnd::InitWindow()
{
RECT rc;
::GetClientRect(this->GetHWND(),&rc); rc.top += ;
rc.left += ;
rc.right += -;
rc.bottom += -; CefWindowInfo info;
info.SetAsChild(*this, rc); TCHAR tszModule[MAX_PATH + ] = { };
::GetModuleFileName(NULL, tszModule, MAX_PATH);
::PathRemoveFileSpec(tszModule); wstring url =tszModule;
url+=L"\\JS C++.html"; CefBrowserSettings settings1;
CefBrowserHost::CreateBrowser(info, m_handler.get(), CefString ("http://www.baidu.com"), settings1, NULL); //打开百度
//CefBrowserHost::CreateBrowser(info, m_handler.get(), CefString (url), settings1, NULL); //打开自己写的html
}

6.duilib窗口关闭时需要重写LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 这个虚函数,在这个虚函数中关闭CEF浏览器

LRESULT CMainFrameWnd::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ if (m_handler && !m_handler->IsClosing()) {
//第一次响应WM_CLOSE消息时
CefRefPtr<CefBrowser> browser = m_handler->GetBrowser();
if (browser.get()) {
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false); // Cancel the close.
return ;
}
}
//第二次响应WM_CLOSE消息时
::PostQuitMessage(1L);
return ;
}

7.如果想让浏览器随着窗口大小变化自适应还需要重写LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)这个虚函数

LRESULT CMainFrameWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
WindowImplBase::OnSize(uMsg,wParam,lParam,bHandled); if (m_handler != NULL){
CefRefPtr<CefBrowser> browser = m_handler->GetBrowser();
if (browser){
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle(); RECT rt;
::GetClientRect(m_hWnd, &rt); int cx = rt.right - rt.left -; int cy = rt.bottom - rt.top -; ::MoveWindow(hwnd, , , cx, cy, TRUE);
}
} return ;
}

8.按照这个流程走下来,可以正常显示,先看一下效果图

同时看一下进程个数:

大家应该注意到上面标注红颜色的三行代码,我在刚开始嵌入时,把这三行代码忘了没写,就出现一个问题,点"X"关闭,程序正常退出了,但有个窗口进程没退出,桌面上留下一个空白窗口,资源管理器中有显示一个进程没退出。

后来反复检查,加上那三行代码后,程序正常退出了,最后看看那三行代码的意思

///
// This function should be called from the application entry point function to
// execute a secondary process. It can be used to run secondary processes from
// the browser client executable (default behavior) or from a separate
// executable specified by the CefSettings.browser_subprocess_path value. If
// called for the browser process (identified by no "type" command-line value)
// it will return immediately with a value of -1. If called for a recognized
// secondary process it will block until the process should exit and then return
// the process exit code. The |application| parameter may be empty. The
// |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
// cef_sandbox_win.h for details).
///
/*--cef(api_hash_check,optional_param=application,
optional_param=windows_sandbox_info)--*/
int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application,
void* windows_sandbox_info);

但是加载本地的html文件,就是没写那三行代码,也不出现上面的问题,感觉很奇怪

9.Debug模式和Release模式配置

首先 在bin目录下放release版的 libcef.dll

对于链接cef的lib,在Debug模式下加载Debug的libcef.lib和libcef_dll_wrapper.lib,Release加载Release的libcef.lib和ibcef_dll_wrapper.lib

#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\DuiLib_ud.lib")
# pragma comment(lib, "..\\Lib\\Debug\\libcef.lib")
# pragma comment(lib, "..\\Lib\\Debug\\libcef_dll_wrapper.lib")
# else
# pragma comment(lib, "..\\Lib\\DuiLib_d.lib")
# endif
#else
# ifdef _UNICODE
# pragma comment(lib, "..\\Lib\\DuiLib_u.lib")
# pragma comment(lib, "..\\Lib\\Release\\libcef.lib")
# pragma comment(lib, "..\\Lib\\Release\\libcef_dll_wrapper.lib")
# else
# pragma comment(lib, "..\\Lib\\DuiLib.lib")
# endif
#endif

这样配置  我们Debug调试 或者发布Release  程序都正常运行

点击下载:CEF嵌入DuilibDemo

最新文章

  1. PHP使用XHProf进行性能分析
  2. 【深入JVM内核—原理、诊断与优化】第2期开课了
  3. java获取客服端信息(系统,浏览器等)
  4. 几种连接数据库的OLEDB驱动程序
  5. 系统监控的一些工具w , vmstat
  6. BOM操作写法实例
  7. Spring 的优秀工具类盘点第 2 部分
  8. Linux开机禁用开启防火墙
  9. IOS UI 第十篇: UITABLEVIEW
  10. Lumen框架—升级改造之路-仓储层
  11. 异步多线程 Async
  12. GridView用法
  13. CentOS6.9切换root用户su root输入正确密码后一直提示Incorrect password,如何解决?
  14. 【性能测试】LoadRunner11安装(包含破解、汉化)
  15. WebStorm 破解方法
  16. mkdir npm
  17. FileStream说明
  18. 第一册:lesson ninety-three。
  19. kali渗透测试之缓冲区溢出实例-windows,POP3,SLmail
  20. 2017-2018-2 20155333 《网络对抗技术》 Exp1 PC平台逆向破解

热门文章

  1. 浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案
  2. dom4j学习
  3. 关于CLR、CIL、CTS、CLS、CLI、BCL和FCL
  4. http-code 未译
  5. android:descendantFocusability用法简析
  6. kali 下文件操作
  7. 不同数据库中同一张表的SQL循环修改语句
  8. Testlink部署全攻略
  9. iOS _C语言_1
  10. linux昨天修改的文件