CEF3嵌入到win32项目

一、编译CEF3源码

     编译源码请参考:https://blog.csdn.net/lengyue2015/article/details/77972035

二、创建一个win32项目

     这里我创建了一个TestCef名称的项目,如图所示:

     CEF3嵌入到win32项目_第1张图片

三、准备cef3头文件

      然后我们将刚才我们编译的cef3源码路径下的include文件夹拷贝到我们的项目路径下,如图所示:

     CEF3嵌入到win32项目_第2张图片

   这里include目录下面是我们项目需要使用的cef3相关的头文件。

四、引入lib库

   在我们的项目源码路径下创建lib文件夹,lib文件夹分别创建debug和release两个文件夹,如图所示:

   CEF3嵌入到win32项目_第3张图片

CEF3嵌入到win32项目_第4张图片

然后我们将编译好的debug和release版本的libcef_dll_wrapper.lib库拷贝到上面debug、release两个文件夹中,由于

libcef.lib库是谷歌已经给我们编译好的,我们直接就可以使用,将libcef.lib也拷贝到相应的文件夹中,如图所示:

CEF3嵌入到win32项目_第5张图片

CEF3嵌入到win32项目_第6张图片

五、配置项目库路径

     这里我们要配置cef3的库路径,右键项目-》属性-》连接器-》常规-》附加库目录,这里输入lib\debug,如图所示:

      CEF3嵌入到win32项目_第7张图片

然后选择输入-》附加依赖项,然后输入libcef.lib、libcef_dll_wrapper.lib两个库,如图所示:

      CEF3嵌入到win32项目_第8张图片

六、代码生成配置

    项目属性-》C/C++-》代码生成-》运行库,然后选择多线程调试(/MTD),如图所示:

    CEF3嵌入到win32项目_第9张图片

七、编写代码

      我们新建两个类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;
}

然后我们进行编译代码,这时候编译通过,如图所示:

CEF3嵌入到win32项目_第10张图片

但此时还不能运行,我们需要将cef相关的dll拷贝到我们生成的debug目录(拷贝就拷贝我们编译的libcef_dll_wrapper项目生成的相关dll),如图所示:

CEF3嵌入到win32项目_第11张图片

然后我们运行程序,如图所示:

CEF3嵌入到win32项目_第12张图片

上图虽然程序运行成功,但实际上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.manifestcompatibility.manifest文件拷贝到我们的项目中,如图所示:

CEF3嵌入到win32项目_第13张图片

然后项目属性-》生成事件-》后期生成事件-》命令行,输入如下命令:

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

如图所示:

CEF3嵌入到win32项目_第14张图片

然后再重新生成项目就可以访问了,如下图所示:

CEF3嵌入到win32项目_第15张图片

至此,cef内嵌win32测试项目完成。

release模式的配置也一致。

源代码下载路径:点击打开链接

你可能感兴趣的:(VC++)