1. 程式人生 > >基於cef3瀏覽器開發經歷

基於cef3瀏覽器開發經歷

下載地址

cef3下載地址
說明:
1. Standard Distribution 裡面包含了一些動態和靜態庫及原始碼
3. Sample Application 一個典型的示例程式
2. Release 裡面僅有一個libcef.pdb

編譯

下載好後,需要自行編譯一個libcef_dll_wrapper.lib庫檔案,編譯方法:
1. 下載一個cmake程式
2. 安裝好,配置環境變數,保證cmake命令能夠響應(或使用gui)
3.解壓下載好的原始碼(例如解壓到:D:\Longruan\third\trunk\cef_3.3396.1775)資料夾
4.進入資料夾下(D:\Longruan\third\trunk\cef_3.3396.1775)目錄
5.輸入命令如下

 cmake -G "Visual Studio 10"

等待執行完畢
6. 開啟cef.sln工程,編譯libcef_dll_wrapper工程,即可。

踩過的坑

  1. cef3開發的瀏覽器,關閉時程式崩潰
CefShutdown(); // 執行這句話,程式崩潰

相信使用最新的cef庫的同學會遇到這個問題。cef的示例程式裡有完整的示例,基本能夠滿足要求。但是cef的示例使用了單例,在自己的程式裡,如果把cef嵌入到自己的對話方塊中,cef是作為一個child存在的,需要把單例去掉(使用類成員可解決這個問題)。

單例模式去掉,使用時用類的成員函式來定義。

  1. openstack novnc 介面顯示10006,連線不成功,但是使用chrome/firfox等都可以
    我下了好幾個版本的cef3,使用3.3396.1775這個版本是可以顯示novnc介面。至於為何有的版本不可用,未知。
    可以將網址輸入到cefclient.exe來測試,看看能否使用。

  2. novnc介面顯示,但是不響應滑鼠
    novnc不響應滑鼠,有的chrome瀏覽器也不響應。why?why?why?不肯能吧。問了相關人員,說清理快取。。。怎麼肯能呢~我一直用隱身模式好吧。解決方法如下:

chrome瀏覽器解決方法

在chrome瀏覽器裡輸入如下地址:

chrome://flags/#touch-events

下面的黃色字型設定disabled
這裡寫圖片描述
重啟後,即可使用
參考地址
chrome命令列引數表

cef3解決方法
聯想chrome是怎麼解決的,猜想cef3是可以通過傳遞command-line來解決這個問題.可以參考chrome命令列引數。設定touch-events。

解決程式碼,增加一個webapp,來載入command-line

#ifndef WEB_APP_HPP
#define WEB_APP_HPP

#include "include/cef_app.h"

// Implement application-level callbacks for the browser process.
class CWebApp : public CefApp, public CefBrowserProcessHandler {
public:
    CWebApp(){}

    // CefApp methods:
    virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
        OVERRIDE {
            return this;
    }

    // CefBrowserProcessHandler methods:
    virtual void OnContextInitialized() OVERRIDE{
        CEF_REQUIRE_UI_THREAD();
        CefRefPtr<CefCommandLine> command_line =
            CefCommandLine::GetGlobalCommandLine();

    }
    virtual void OnBeforeCommandLineProcessing(
        const CefString& process_type,
        CefRefPtr<CefCommandLine> command_line) OVERRIDE{
            CEF_REQUIRE_UI_THREAD();
             command_line->AppendSwitch("process-per-site");
             // 解決novnc滑鼠不響應問題,禁用touch-events
             command_line->AppendSwitchWithValue("touch-events","disabled");
    }
private:
    // Include the default reference counting implementation.
    IMPLEMENT_REFCOUNTING(CWebApp);
};

#endif  // 

在建立web時,方法如下:

...

void CWebClient::CreateBrowser(HWND hParentWnd, const RECT& rect)
{
    CEF_REQUIRE_UI_THREAD();
    CefEnableHighDPISupport();
    CefSettings cSettings;  
    CefSettingsTraits::init( &cSettings);  
    cSettings.multi_threaded_message_loop = true;  
    CefRefPtr<CWebApp> spApp(new CWebApp);  
    //CefInitialize( cSettings, spApp); 
    CefMainArgs main_args(::GetModuleHandle(NULL));
    int exit_code = CefExecuteProcess(main_args, spApp.get(),NULL);
    if (exit_code>0)
    {
        return;
    }
    CefInitialize(main_args, cSettings, spApp.get(), NULL);
    CefWindowInfo info; 
    info.SetAsChild( hParentWnd, rect);
    CefBrowserSettings browserSettings;  
    if( m_strHomePage.empty()) 
        m_strHomePage = L"http://www.baidu.com/";
    CefBrowserHost::CreateBrowser(info,this, m_strHomePage,
        browserSettings, NULL);
}
...

這裡是建立一個子對話方塊。command_line需要在app裡處理

cef3右鍵選單遮蔽

可能需要做個UI介面或自己定製右鍵選單,使用下列程式碼

  CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE {
      return this;
  }
bool CWebClient::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags)OVERRIDE
{
        CEF_REQUIRE_UI_THREAD();
        return false;
}

void CWebClient::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model) OVERRIDE
{
    if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
        if (model->GetCount() > 0)
        {
            model->Clear();
        }
    }
}

這三個函式都需要重寫.尤其是別忘了GetContextMenuHandler,很多同學把這個給忘了,導致自定義失敗。

CefClient 中返回的回撥類包括:

CefContextMenuHandler,回撥類,主要用於處理 Context Menu 事件。

CefDialogHandler,回撥類,主要用來處理對話方塊事件。

CefDisplayHandler,回撥類,處理與頁面狀態相關的事件,如頁面載入情況的變化,位址列變化,標題變化等事件。

CefDownloadHandler,回撥類,主要用來處理檔案下載。

CefFocusHandler,回撥類,主要用來處理焦點事件。

CefGeolocationHandler,回撥類,用於申請 geolocation 許可權。

CefJSDialogHandler,回撥類,主要用來處理 JS 對話方塊事件。

CefKeyboardHandler,回撥類,主要用來處理鍵盤輸入事件。

CefLifeSpanHandler,回撥類,主要用來處理與瀏覽器生命週期相關的事件,與瀏覽器物件的建立、銷燬以及彈出框的管理。

CefLoadHandler,回撥類,主要用來處理瀏覽器頁面載入狀態的變化,如頁面載入開始,完成,出錯等。

CefRenderHandler,回撥類,主要用來處在在視窗渲染功能被關閉的情況下的事件。

CefRequestHandler,回撥類,主要用來處理與瀏覽器請求相關的的事件,如資源的的載入,重定向等。

重寫一個方法,需要繼承client,返回對應的this指標才能使用,例如右鍵選單自定義功能。