文章目录
libcef是一个封装良好的浏览器框架,它将具体的实现细节封装在抽象类中,而一般使用者可以通过继承和多态来修改它的局部功能过程,以此达到定制的目的。初学者可以先使用,然后再深究。本文从官方的一个例子初步讲解如何简单构建一个浏览器窗口。初步熟悉使用流程中的概念。
1.程序入口文件-cefsimple_win.cc
- 1.程序入口文件-cefsimple_win.cc
- 2.应用程序对象--SimpleApp
- 3.应用程序句柄回调
- 4.作者答疑
在主程序文件中,首先打开了High-DPI支持,然后解析了进程传递进来的参数,CefExecuteProcess() 会根据不同的命令行参数来执行不同的进程,如果是浏览器进程,该函数立即返回,返回值为 -1。如果是其他进程,则在退出时才返回,返回值是一个大于0的数。接着构建一个应用程序实例,并将命令行参数和浏览器参数设置传递进App对象,运行浏览器进程消息循环,保证程序等待CefQuitMessageLoop()被调用,最后关闭CEF。注意一点,所有进程的入口点都在此,由CefExecuteProcess() 启动不同的功能的其它模块。
#include
#include "include/cef_sandbox_win.h"
#include "tests/cefsimple/simple_app.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 may not link successfully with all VS
// versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif
//win32 进程入口函数
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.
//在Windows 7或更新版本上启用High-DPI支持。
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.
//为CEF提供命令行参数。
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.
//CEF应用程序有多个子进程(渲染、插件、GPU等)共享相同的可执行文件。该函数检查命令行,如果是子进程,则执行相应的逻辑。
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.
//SimpleApp 为浏览器进程实现应用程序级回调。 CEF 初始化后,它将在 OnContextInitialized() 中创建第一个浏览器实例。
CefRefPtr app(new SimpleApp);
// Initialize CEF.
// 初始化CEF
CefInitialize(main_args, settings, app.get(), sandbox_info);
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
// called.
//运行 CEF 消息循环。 这将阻塞,直到 CefQuitMessageLoop() 被调用。
CefRunMessageLoop();
// Shut down CEF.
//关闭CEF
CefShutdown();
return 0;
}
2.应用程序对象–SimpleApp
CefApp接口提供了不同进程的可定制回调函数,每一个进程对应一个CefApp接口。CefBrowserProcessHandler对应浏览器进程的回调,CefRenderProcessHandler对应渲染进程的回调。在在OnContextInitialized回调函数中进行应用程序参数初始化和窗口创建。
simple_app.h文件
#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#include "include/cef_app.h"
// Implement application-level callbacks for the browser process.
// 为浏览器进程实现应用级回调
class SimpleApp : public CefApp, public CefBrowserProcessHandler {
public:
SimpleApp();
// CefApp methods:
virtual CefRefPtr GetBrowserProcessHandler()
OVERRIDE {
return this;
}
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleApp);
};
#endif // CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
simple_app.cc文件
#include "tests/cefsimple/simple_app.h"
#include
#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 "tests/cefsimple/simple_handler.h"
namespace
{
// When using the Views framework this object provides the delegate
// implementation for the CefWindow that hosts the Views-based browser.
//使用 Views 框架时,此对象为承载基于 Views 的浏览器的 CefWindow 提供委托实现。
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;
}
CefSize GetPreferredSize(CefRefPtr view) OVERRIDE
{
return CefSize(800, 600);//窗口大小
}
private:
CefRefPtr browser_view_;
IMPLEMENT_REFCOUNTING(SimpleWindowDelegate);
DISALLOW_COPY_AND_ASSIGN(SimpleWindowDelegate);
};
} // namespace
SimpleApp::SimpleApp() {}
/*浏览器应用程序初始化*/
void SimpleApp::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 SimpleHandler(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) //Mac
{
// Create the BrowserView.
CefRefPtr browser_view = CefBrowserView::CreateBrowserView(
handler, url, browser_settings, NULL, NULL, NULL);
// Create the Window. It will show itself after creation.
//创建窗口
CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view));
}
else //linux和windows
{
// 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, "test simple cef");//窗口标题
#endif
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings,
NULL, NULL);
}
}
3.应用程序句柄回调
CefClient,CefDisplayHandler,CefLifeSpanHandler,CefLoadHandler,这些handler的都是基于功能的回调,应用开发者应该提供对应的handler实现,然后提供应用程序获取对应handler实体。 simple_handler.h文件
#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
#include "include/cef_client.h"
#include
class SimpleHandler : public CefClient,
public CefDisplayHandler,//显示状态相关接口
public CefLifeSpanHandler,
public CefLoadHandler {
public:
explicit SimpleHandler(bool use_views);
~SimpleHandler();
// Provide access to the single global instance of this object.
static SimpleHandler* 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(SimpleHandler);
};
#endif // CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
simple_handler.cc文件
#include "tests/cefsimple/simple_handler.h"
#include
#include
#include "include/base/cef_bind.h"
#include "include/cef_app.h"
#include "include/cef_parser.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"
namespace
{
SimpleHandler *g_instance = NULL;
// Returns a data: URI with the specified contents.
std::string GetDataURI(const std::string &data, const std::string &mime_type)
{
return "data:" + mime_type + ";base64," +
CefURIEncode(CefBase64Encode(data.data(), data.size()), false)
.ToString();
}
} // namespace
SimpleHandler::SimpleHandler(bool use_views)
: use_views_(use_views), is_closing_(false)
{
DCHECK(!g_instance);
g_instance = this;
}
SimpleHandler::~SimpleHandler()
{
g_instance = NULL;
}
// static
SimpleHandler *SimpleHandler::GetInstance()
{
return g_instance;
}
void SimpleHandler::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 SimpleHandler::OnAfterCreated(CefRefPtr browser)
{
CEF_REQUIRE_UI_THREAD();
// Add to the list of existing browsers.
browser_list_.push_back(browser);
}
bool SimpleHandler::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 SimpleHandler::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 SimpleHandler::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 using a data: URI.
std::stringstream ss;
ss
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?