编译源码请参考:https://blog.csdn.net/lengyue2015/article/details/77972035
这里我创建了一个TestCef名称的项目,如图所示:
然后我们将刚才我们编译的cef3源码路径下的include文件夹拷贝到我们的项目路径下,如图所示:
这里include目录下面是我们项目需要使用的cef3相关的头文件。
在我们的项目源码路径下创建lib文件夹,lib文件夹分别创建debug和release两个文件夹,如图所示:
然后我们将编译好的debug和release版本的libcef_dll_wrapper.lib库拷贝到上面debug、release两个文件夹中,由于
libcef.lib库是谷歌已经给我们编译好的,我们直接就可以使用,将libcef.lib也拷贝到相应的文件夹中,如图所示:
这里我们要配置cef3的库路径,右键项目-》属性-》连接器-》常规-》附加库目录,这里输入lib\debug,如图所示:
然后选择输入-》附加依赖项,然后输入libcef.lib、libcef_dll_wrapper.lib两个库,如图所示:
项目属性-》C/C++-》代码生成-》运行库,然后选择多线程调试(/MTD),如图所示:
我们新建两个类TestCefAPP和TestCefHandler,代码如下:
#pragma once
#include "include/cef_app.h"
class TestCefAPP : public CefApp,public CefBrowserProcessHandler
{
public:
TestCefAPP(void);
~TestCefAPP(void);
// CefApp methods:
virtual CefRefPtr GetBrowserProcessHandler()
OVERRIDE { return this; }
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(TestCefAPP);
};
#include "StdAfx.h"
#include "TestCefAPP.h"
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_helpers.h"
#include "TestCefHandler.h"
TestCefAPP::TestCefAPP(void)
{
}
TestCefAPP::~TestCefAPP(void)
{
}
namespace {
// When using the Views framework this object provides the delegate
// implementation for the CefWindow that hosts the Views-based browser.
class SimpleWindowDelegate : public CefWindowDelegate {
public:
explicit SimpleWindowDelegate(CefRefPtr browser_view)
: browser_view_(browser_view) {
}
void OnWindowCreated(CefRefPtr window) OVERRIDE {
// Add the browser view and show the window.
window->AddChildView(browser_view_);
window->Show();
// Give keyboard focus to the browser view.
browser_view_->RequestFocus();
}
void OnWindowDestroyed(CefRefPtr window) OVERRIDE {
browser_view_ = NULL;
}
bool CanClose(CefRefPtr window) OVERRIDE {
// Allow the window to close if the browser says it's OK.
CefRefPtr browser = browser_view_->GetBrowser();
if (browser)
return browser->GetHost()->TryCloseBrowser();
return true;
}
private:
CefRefPtr browser_view_;
IMPLEMENT_REFCOUNTING(SimpleWindowDelegate);
DISALLOW_COPY_AND_ASSIGN(SimpleWindowDelegate);
};
} // namespace
void TestCefAPP::OnContextInitialized() {
CEF_REQUIRE_UI_THREAD();
CefRefPtr command_line =
CefCommandLine::GetGlobalCommandLine();
#if defined(OS_WIN) || defined(OS_LINUX)
// Create the browser using the Views framework if "--use-views" is specified
// via the command-line. Otherwise, create the browser using the native
// platform framework. The Views framework is currently only supported on
// Windows and Linux.
const bool use_views = command_line->HasSwitch("use-views");
#else
const bool use_views = false;
#endif
// SimpleHandler implements browser-level callbacks.
CefRefPtr handler(new TestCefHandler(use_views));
// Specify CEF browser settings here.
CefBrowserSettings browser_settings;
std::string url;
// Check if a "--url=" value was provided via the command-line. If so, use
// that instead of the default URL.
url = command_line->GetSwitchValue("url");
if (url.empty())
url = "http://www.baidu.com";
if (use_views) {
// Create the BrowserView.
CefRefPtr browser_view = CefBrowserView::CreateBrowserView(
handler, url, browser_settings, NULL, NULL);
// Create the Window. It will show itself after creation.
CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view));
} else {
// Information used when creating the native window.
CefWindowInfo window_info;
#if defined(OS_WIN)
// On Windows we need to specify certain flags that will be passed to
// CreateWindowEx().
window_info.SetAsPopup(NULL, "cefsimple");
#endif
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings,
NULL);
}
}
#pragma once
#include "include/cef_client.h"
#include
class TestCefHandler:public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler
{
public:
explicit TestCefHandler(bool use_views);
~TestCefHandler();
// Provide access to the single global instance of this object.
static TestCefHandler* GetInstance();
// CefClient methods:
virtual CefRefPtr GetDisplayHandler() OVERRIDE {
return this;
}
virtual CefRefPtr GetLifeSpanHandler() OVERRIDE {
return this;
}
virtual CefRefPtr GetLoadHandler() OVERRIDE {
return this;
}
// CefDisplayHandler methods:
virtual void OnTitleChange(CefRefPtr browser,
const CefString& title) OVERRIDE;
// CefLifeSpanHandler methods:
virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE;
virtual bool DoClose(CefRefPtr browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE;
// CefLoadHandler methods:
virtual void OnLoadError(CefRefPtr browser,
CefRefPtr 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_; }
private:
// Platform-specific implementation.
void PlatformTitleChange(CefRefPtr browser,
const CefString& title);
// True if the application is using the Views framework.
const bool use_views_;
// List of existing browser windows. Only accessed on the CEF UI thread.
typedef std::list > BrowserList;
BrowserList browser_list_;
bool is_closing_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(TestCefHandler);
};
#include "StdAfx.h"
#include "TestCefHandler.h"
#include "include/base/cef_bind.h"
#include "include/cef_app.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"
#include "include/internal/cef_win.h"
#include
namespace {
TestCefHandler* g_instance = NULL;
} // namespace
TestCefHandler::TestCefHandler(bool use_views)
: use_views_(use_views),
is_closing_(false) {
DCHECK(!g_instance);
g_instance = this;
}
TestCefHandler::~TestCefHandler() {
g_instance = NULL;
}
// static
TestCefHandler* TestCefHandler::GetInstance() {
return g_instance;
}
void TestCefHandler::OnTitleChange(CefRefPtr browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
if (use_views_) {
// Set the title of the window using the Views framework.
CefRefPtr browser_view =
CefBrowserView::GetForBrowser(browser);
if (browser_view) {
CefRefPtr window = browser_view->GetWindow();
if (window)
window->SetTitle(title);
}
} else {
// Set the title of the window using platform APIs.
PlatformTitleChange(browser, title);
}
}
void TestCefHandler::PlatformTitleChange(CefRefPtr browser,
const CefString& title)
{
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
SetWindowText(hwnd, std::wstring(title).c_str());
}
void TestCefHandler::OnAfterCreated(CefRefPtr browser) {
CEF_REQUIRE_UI_THREAD();
// Add to the list of existing browsers.
browser_list_.push_back(browser);
}
bool TestCefHandler::DoClose(CefRefPtr 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) {
// 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 TestCefHandler::OnBeforeClose(CefRefPtr 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();
}
}
void TestCefHandler::OnLoadError(CefRefPtr browser,
CefRefPtr 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 << ""
"Failed to load URL " << std::string(failedUrl) <<
" with error " << std::string(errorText) << " (" << errorCode <<
").
";
frame->LoadString(ss.str(), failedUrl);
}
void TestCefHandler::CloseAllBrowsers(bool force_close) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&TestCefHandler::CloseAllBrowsers, this, force_close));
return;
}
if (browser_list_.empty())
return;
BrowserList::const_iterator it = browser_list_.begin();
for (; it != browser_list_.end(); ++it)
(*it)->GetHost()->CloseBrowser(force_close);
}
然后修改我们的入口函数,如下:
#include "stdafx.h"
#include
#include "include/cef_sandbox_win.h"
#include "TestCefAPP.h"
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
// Uncomment this line to manually enable sandbox support.
// #define CEF_USE_SANDBOX 1
#if defined(CEF_USE_SANDBOX)
// The cef_sandbox.lib static library is currently built with VS2013. It may not
// link successfully with other VS versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif
// Entry point function for all processes.
int APIENTRY wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Enable High-DPI support on Windows 7 or newer.
CefEnableHighDPISupport();
void* sandbox_info = NULL;
#if defined(CEF_USE_SANDBOX)
// Manage the life span of the sandbox information object. This is necessary
// for sandbox support on Windows. See cef_sandbox_win.h for complete details.
CefScopedSandboxInfo scoped_sandbox;
sandbox_info = scoped_sandbox.sandbox_info();
#endif
// Provide CEF with command-line arguments.
CefMainArgs main_args(hInstance);
// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so return here.
return exit_code;
}
// Specify CEF global settings here.
CefSettings settings;
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// SimpleApp implements application-level callbacks for the browser process.
// It will create the first browser instance in OnContextInitialized() after
// CEF has initialized.
CefRefPtr app(new TestCefAPP);
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), sandbox_info);
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
// called.
CefRunMessageLoop();
// Shut down CEF.
CefShutdown();
return 0;
}
然后我们进行编译代码,这时候编译通过,如图所示:
但此时还不能运行,我们需要将cef相关的dll拷贝到我们生成的debug目录(拷贝就拷贝我们编译的libcef_dll_wrapper项目生成的相关dll),如图所示:
然后我们运行程序,如图所示:
上图虽然程序运行成功,但实际上cef库发生错误了,并没有加载出我们代码里给的百度的网址,我们打开debug目录下的debug.log文件,发现cef报了如下错误:
[0625/222437:FATAL:dwrite_font_proxy_init_win.cc(91)] Check failed: fallback_available == base::win::GetVersion() > base::win::VERSION_WIN8 (1 vs. 0)
这个错误表示应用程序需要一个带有相关兼容性条目的app.manifest,这里我们需要将,我们下载的源码路径下测试路径下(tests\cefsimple)的cefsimple.exe.manifest和compatibility.manifest文件拷贝到我们的项目中,如图所示:
然后项目属性-》生成事件-》后期生成事件-》命令行,输入如下命令:
setlocal
mt.exe -nologo -manifest "compatibility.manifest" "TestCef.exe.manifest" -outputresource:"../Debug/TestCef.exe";#1
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
如图所示:
然后再重新生成项目就可以访问了,如下图所示:
至此,cef内嵌win32测试项目完成。
release模式的配置也一致。
源代码下载路径:点击打开链接