您当前的位置: 首页 > 

插件开发

暂无认证

  • 2浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

libcef-cefsimple简单解析-涉及对象及关键类分析-CefApp-CefClient-CefDisplayHandler(七)

插件开发 发布时间:2022-03-20 08:26:36 ,浏览量:2

文章目录
    • 1.程序入口文件-cefsimple_win.cc
    • 2.应用程序对象--SimpleApp
    • 3.应用程序句柄回调
    • 4.作者答疑
  libcef是一个封装良好的浏览器框架,它将具体的实现细节封装在抽象类中,而一般使用者可以通过继承和多态来修改它的局部功能过程,以此达到定制的目的。初学者可以先使用,然后再深究。本文从官方的一个例子初步讲解如何简单构建一个浏览器窗口。初步熟悉使用流程中的概念。

1.程序入口文件-cefsimple_win.cc

  在主程序文件中,首先打开了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             
关注
打赏
1665481431
查看更多评论
0.0439s