基于cef3浏览器开发经历

版权声明:本文为博主原创文章,未经博主允许不得转载。若有疑问,请邮件:[email protected] https://blog.csdn.net/cloudmq/article/details/80598590

下载地址

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指针才能使用,例如右键菜单自定义功能。

猜你喜欢

转载自blog.csdn.net/cloudmq/article/details/80598590