CEF3 C++接口实现自定义浏览器[simple version]

2023-05-16

目录

目录... 1

一、工具准备... 2

二、编译C++接口... 2

三、实现浏览器... 5

浏览器定制... 5

浏览器默认最大化,标题从配置文件读取... 5

设置浏览器中文环境,开启npapi插件功能,并注册身份证阅读器插件(见第四节)    7

文件下载... 8

首先浏览器处理类要继承CefDownloadHandler 类... 8

并提供回调接口(继承任何处理类都要提供类似的回调接口)... 8

文件下载具体重载函数... 8

文件下载重载函数实现... 9

F5刷新功能... 10

继承按键处理类... 10

提供回调接口... 10

重载声明... 11

重载实现... 11

右键菜单添加刷新按钮... 12

继承菜单处理类... 12

提供回调接口... 12

重载声明... 12

重载实现... 13

四、身份证阅读器插件开发... 14

工程建立... 14

首先下载npapi插件开发包,解压进入... 14

新建win32 dll工程,工程名以NP开头,将上图的文件引入工程。... 14

新建stdafx.h头文件,加入... 15

设置预处理... 16

设置头文件包含... 16

功能实现... 17

加载身份证识别模块... 17

定义功能标识... 17

实现具体功能... 18

定义插件模块,其中MIMEType,是在html中调用的关键字... 19

生成插件... 20

插件部署... 20

插件测试... 21

插件调试... 23

浏览器增加启动参数... 23

启动浏览器... 24

在vs中打好断点,附加到进程... 24

进入断点... 25

 

一、工具准备

  1. vs 2017 community
  2. cmake 3.7 +
  3. cef_binary_3.2357.1271.g8e0674e_windows32,包含已编译好的c接口动态库和c++接口源码,C++接口默认没有编译,以源码提供

 

 

二、编译C++接口

生成vs工程

进入cef源码根目录,进入libcef_dll。此目录是c++接口源码目录。C接口动态库放在根目录的Release目录中。输入命令cmake -G "Visual Studio 15",生成VS工程

 

打开vs工程

 

右击项目“libcef_dll_wrapper”,设置头文件包含目录

 

加入预处理命令  NOMINMAX

 

生成“libcef_dll_wrapper”项目

生成的c++接口

三、实现浏览器

浏览器定制

新建一个win32GUI的空工程,将cef目录下的cefsimple相关文件拷贝进来,cefsimple实现很简单就是打开一个网页,我们来新增一些功能

 

 

浏览器默认最大化,标题从配置文件读取

void SimpleApp::OnContextInitialized() {

  CEF_REQUIRE_UI_THREAD();

 

  // 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

 

  // 设置窗口样式

  window_info.style = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE;

  UINT width = GetSystemMetrics(SM_CXSCREEN);

  UINT height = GetSystemMetrics(SM_CYSCREEN);

  window_info.parent_window = NULL;

  window_info.x = -1;

  window_info.y = -1;

  window_info.width = width;

  window_info.height = height;

 

  // SimpleHandler implements browser-level callbacks.

  CefRefPtr<SimpleHandler> handler(new SimpleHandler());

 

  // Specify CEF browser settings here.

  CefBrowserSettings browser_settings;

  char * code = "UTF-8";

  cef_string_t encode = {};

  cef_string_utf8_to_utf16(code, strlen(code), &encode);

  browser_settings.default_encoding = encode;

 

  //设置窗口标题

  WCHAR window_name[1024];

  GetPrivateProfileStringW(L"GMS", L"title", L"", window_name, 1024, L".\\gms.ini");

  cef_string_wide_to_utf16(window_name, wcslen(window_name), &window_info.window_name);

 

  // 设置访问地址

  char url[1024];

  GetPrivateProfileStringA("GMS", "url", "", url, 1024, ".\\gms.ini");

 

 

  // Create the first browser window.

 

  CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL);

}

 

设置浏览器中文环境,开启npapi插件功能,并注册身份证阅读器插件(见第四节)

void SimpleApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr<CefCommandLine> command_line) {

    //开启插件

    command_line->AppendSwitch("--enable-npapi");

    //设置中文语言环境

    command_line->AppendSwitchWithValue("--lang", "zh-CN");

    command_line->AppendSwitchWithValue("register-netscape-plugins","NPRDCARD.dll/nprdcard-plugin");

    return;

}

文件下载

首先浏览器处理类要继承CefDownloadHandler 类

并提供回调接口(继承任何处理类都要提供类似的回调接口)

  virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() //实现 

  {

      return this;

  }

 

文件下载具体重载函数

  //重载文件下载方法

  virtual void OnBeforeDownload(

      CefRefPtr<CefBrowser> browser,

      CefRefPtr<CefDownloadItem> download_item,

      const CefString& suggested_name,

      CefRefPtr<CefBeforeDownloadCallback> callback) OVERRIDE;

 

  virtual void OnDownloadUpdated(

      CefRefPtr<CefBrowser> browser,

      CefRefPtr<CefDownloadItem> download_item,

      CefRefPtr<CefDownloadItemCallback> callback) OVERRIDE;

 

文件下载重载函数实现

//文件下载方法重载

void SimpleHandler::OnBeforeDownload(

    CefRefPtr<CefBrowser> browser,

    CefRefPtr<CefDownloadItem> download_item,

    const CefString& suggested_name,

    CefRefPtr<CefBeforeDownloadCallback> callback)

{

    callback->Continue(download_item->GetURL(), true);

}

 

void SimpleHandler::OnDownloadUpdated(

    CefRefPtr<CefBrowser> browser,

    CefRefPtr<CefDownloadItem> download_item,

    CefRefPtr<CefDownloadItemCallback> callback)

{

    if (download_item->IsComplete())

    {

        //MessageBox.Show("下载成功");

        if (browser->IsPopup() && !browser->HasDocument())

        {

            //browser->GetHost()->ParentWindowWillClose();

            browser->GetHost()->CloseBrowser(true);

        }

    }

}

F5刷新功能

继承按键处理类

提供回调接口

  virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() //实现 

  {

      return this;

  }

重载声明

  //按键处理

  virtual bool OnPreKeyEvent(CefRefPtr<CefBrowser> browser,

      const CefKeyEvent& event,

      CefEventHandle os_event,

      bool* is_keyboard_shortcut) OVERRIDE;

 

  virtual bool OnKeyEvent(CefRefPtr<CefBrowser> browser,

      const CefKeyEvent& event,

      CefEventHandle os_event) OVERRIDE;

 

重载实现

bool SimpleHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,

    const CefKeyEvent& event,

    CefEventHandle os_event,

    bool* is_keyboard_shortcut) {

    if(event.windows_key_code==116)//F5刷新

    browser->Reload();

    return false;

}

 

bool SimpleHandler::OnKeyEvent(CefRefPtr<CefBrowser> browser,

    const CefKeyEvent& event,

    CefEventHandle os_event) {

    return false;

}

 

右键菜单添加刷新按钮

继承菜单处理类

提供回调接口

  virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() //实现 

  {

      return this;

  }

 

重载声明

  // 右键菜单处理

  virtual void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,

      CefRefPtr<CefFrame> frame,

      CefRefPtr<CefContextMenuParams> params,

      CefRefPtr<CefMenuModel> model) OVERRIDE;

 

  virtual bool OnContextMenuCommand(CefRefPtr<CefBrowser> browser,

      CefRefPtr<CefFrame> frame,

      CefRefPtr<CefContextMenuParams> params,

      int command_id,

      EventFlags event_flags) OVERRIDE;

 

重载实现

 

void SimpleHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,

    CefRefPtr<CefFrame> frame,

    CefRefPtr<CefContextMenuParams> params,

    CefRefPtr<CefMenuModel> model) {

    if (model->GetCount() > 0) {// 刷新菜单

        model->AddSeparator();

        model->AddItem(ID_CMD_REFRESH, __TEXT("刷新"));

    }

   

}

 

bool SimpleHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser,

    CefRefPtr<CefFrame> frame,

    CefRefPtr<CefContextMenuParams> params,

    int command_id,EventFlags event_flags) {

    switch (command_id)

    {

    case ID_CMD_REFRESH:

        browser->Reload();

        break;

    default:

        break;

    }

    return false;

}

四、身份证阅读器插件开发

工程建立

首先下载npapi插件开发包,解压进入

新建win32 dll工程,工程名以NP开头,将上图的文件引入工程。

 

新建stdafx.h头文件,加入

//kk: common and often used headers

 

 

#include <windows.h>

#include <windowsx.h>

#include <stdio.h>

#include <atlstr.h>

 

//Mozilla-API

#include <npfunctions.h>

#include <npruntime.h>

#include "npruntime.h"

 

#define TRACE __noop

并在plugin.cpp中引用此头文件

 

设置预处理

 

设置头文件包含

 

功能实现

加载身份证识别模块

    ScriptablePluginObject(NPP npp)

        : ScriptablePluginObjectBase(npp)

    {

        //***************************加载神思模块**************

        hInstance = LoadLibrary("RdCard.dll");

        if (!hInstance) {

            ::MessageBox(NULL, __TEXT("加载神思接口失败,请检查 RdCard.dll,重新打开页面"), __T("提示"), MB_OK);

        }

    }

 

    ~ScriptablePluginObject() {

        FreeLibrary(hInstance);

    }

 

定义功能标识

// 拓展 增加方法

 

// 获取身份证姓名方法

static NPIdentifier sIdCardName_id;

 

//测试阅读器是否连接

static NPIdentifier sIdCardStatus_id;

 

 

修改插件方法判断函数

// ********************测试插件是否有此方法**********************

bool

ScriptablePluginObject::HasMethod(NPIdentifier name)

{

    return (name == sFoo_id || name == sIdCardStatus_id || name == sIdCardName_id);

}

 

 

实现具体功能

// 插件提供方法调用接口

bool

ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,

    uint32_t argCount, NPVariant *result)

{

    if (name == sFoo_id) {// foo 方法

 

        ::MessageBox(NULL, __TEXT("开始调用foo方法"), __T("提示"), MB_OKCANCEL);

        char* m_szTextGui = "我是foo方法调用返回的结果";

 

        STRINGZ_TO_NPVARIANT(toGBK(m_szTextGui), *result);

 

 

        return true;

    }

    else if(name == sIdCardStatus_id) {//测试身份证阅读器是否连接

        ::MessageBox(NULL, __TEXT("开始调用IsConnect方法"), __T("提示"), MB_OKCANCEL);

 

        typedef int (*FUN)(...);

        FUN fun;

        fun = (FUN)GetProcAddress(hInstance, "IsConnect");

        if (!fun) {

            ::MessageBox(NULL, __TEXT(" RdCard.dll 中没有 IsConnect 函数"), __T("提示"), MB_OK);

            return false;

        }

           

        bool rst = fun();

        BOOLEAN_TO_NPVARIANT(rst, *result);

        return true;

 

    }

    else if (name == sIdCardName_id) {// 获取身份证姓名

       

        typedef int (*FUN)(...);

        FUN fun;

        fun = (FUN)GetProcAddress(hInstance, "GetName");

        if (!fun) {

            ::MessageBox(NULL, __TEXT(" RdCard.dll 中没有 GetName 函数"), __T("提示"), MB_OK);

            return false;

        }

        ::MessageBox(NULL, __TEXT("开始调用getName方法"), __T("提示"), MB_OKCANCEL);

        char name[20];

        fun(name);

        STRINGZ_TO_NPVARIANT(toGBK(name),*result);

        return true;

 

 

    }

 

    return false;

}

 

定义插件模块,其中MIMEType,是在html中调用的关键字

生成插件

 

插件部署

将生成的NPRDCARD.dll放入浏览器目录的plugins目录下

身份证阅读器依赖的dll放在浏览器可执行文件目录下

 

插件测试

测试身份证阅读器是否连接

 

插件调试

浏览器增加启动参数

启动浏览器

在vs中打好断点,附加到进程

 

点击测试是否连接设备

进入断点

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CEF3 C++接口实现自定义浏览器[simple version] 的相关文章

随机推荐

  • 虚拟机使用主机显卡(hyper-v和WSL2)

    我的系统版本WSL2 43 Ubuntu20 04 43 CUDA启用WSL2 43 安装Ubuntu20 04 主机安装WSL Cuda显卡驱动WSL2 Ubuntu安装cuda和cudnncudacudnn安装TensorFlow使用自
  • Linux 系统 “Read-only file system” ” 错误 与 解决方法

    这个问题经常发生在有大量磁盘读写操作且磁盘分区很大的环境中 xff0c 下面简单描述下此案例的应用环境 xff1a 这是一个 Web 服务器故障案例 xff0c 客户利用两台服务器加一个磁盘阵列做了一个双机热备的 Web 系统 xff0c
  • Failed to start bean ‘documentationPluginsBootstrapper‘; nested exception is java.lang.NullPointerEx

    看了以上午 xff0c 终于找到了问题所在0 0 swagger 与 springboot 使用的时候 xff0c 有一个版本问题 xff1a swagger版本springboot版本2 x2 7 x 一下3 x2 7 x 及以上 不多说
  • 黑客圈最受欢迎的21个 Kali Linux 工具,你都用过哪几个?

    这里是最好的 Kali Linux 工具列表 xff0c 它们可以让你评估 Web 服务器的安全性 xff0c 并帮助你执行黑客渗透测试 如果你读过 Kali Linux 点评 xff0c 你就知道为什么它被认为是最好的黑客渗透测试的 Li
  • 今天第一次加入

    64 TOC今天第一次加入进来 欢迎使用Markdown编辑器 你好 xff01 这是你第一次使用 Markdown编辑器 所展示的欢迎页 如果你想学习如何使用Markdown编辑器 可以仔细阅读这篇文章 xff0c 了解一下Markdow
  • 学习OpenStack之环境部署一篇就够啦!!!(带你走进OpenStack世界)

    文章目录 一 xff1a 项目拓扑1 1 xff1a 环境介绍 二 xff1a 系统环境配置2 1 xff1a 安装 配置MariaDB2 2 xff1a 安装RabbitMQ2 3 xff1a 安装memcached 三 xff1a Ke
  • ccf 炉石传说

    import java util ArrayList import java util Scanner span class hljs comment date 9 11 17 author chaomaer span span class
  • python之paramiko文件夹远程上传

    Paramiko模块是一个用来连接远程服务器 xff0c 进行文件上传下载和shell命令执行的PYTHON模块 xff0c 使用方便 但是它不支持整个文件夹的上传 xff0c 近期需要分发上传一个离线工具包到服务器去执行 xff0c 考虑
  • form表单提交后,页面弹出成功或者失败的信息

    Ssm 中用RedirectAttributes做提示消息 96 span class token annotation punctuation 64 RequiresPermissions span span class token pu
  • Oracle提示表空间不足ORA-01653:

    这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题 xff0c 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中 居左 居右SmartyP
  • 递归删除树节点

    public int delete Long id 删除权限的集合ids List lt Long gt ids 61 new ArrayList lt gt ids add id 递归的将一级分类下的id也加入到集合中 this getI
  • 解决报错:sufficient buffer space or because a queue was full

    An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was
  • java判断字符串(含中文)的内容相似度

    span class token comment 判断地址相似 此处简单的判断字符串的内容80 相似即可 64 param str1 64 param str2 64 return span span class token keyword
  • display:table-cell实现两栏自适应布局

    前面介绍了 float实现两栏自适应布局 float 43 overflow实现两栏自适应布局 xff0c 现在看下table如何实现两栏自适应布局 display table cell lt table gt lt table gt 里的
  • Microsoft Visual C++ 14.0 is required.

    Microsoft Visual C 43 43 14 0 is required Get it with Microsoft Visual C 43 43 Build Tools 当我们安装绝大部分python包的时候可以通过pip in
  • ubuntu20.04离线安装rabbitvcs

    在内网开发的时候 xff0c 管理更新代码非常不方便 xff0c 使用svn是非常普遍的现象 小乌龟svn貌似只有windows版本的 xff0c 在linux系统下与其操作接近的软件rabbitcvs变成了最好的选择 在线安装rabbit
  • 实机安装CentOS7.9操作系统图文(保姆级)教程

    一 制作启动U盘 1 下载Ventoy软件 去Ventoy官网下载Ventoy软件 xff08 Download Ventoy xff09 如下图界面 2 制作启动盘 选择合适的版本以及平台下载好之后 xff0c 进行解压 xff0c 解压
  • Angular8升级至Angular13遇到的问题

    根据项目需求 xff0c 需要把Angular版本从8升级到13 xff0c 无法从8直接升至13 xff0c 需要一级一级的升级 xff0c 本文介绍了在升级Angular版本的时候的一种报错和解决办法 一 开始之前 首先确保你 Node
  • mysql怎么查询表的大小

    通过sql语句查询整个数据库的容量 xff0c 或是单独查看表所占容量 1 要查询表所占的容量 xff0c 就是把表的数据和索引加起来就可以了 1 select sum DATA LENGTH 43 sum INDEX LENGTH fro
  • CEF3 C++接口实现自定义浏览器[simple version]

    目录 目录 1 一 工具准备 2 二 编译C 43 43 接口 2 三 实现浏览器 5 浏览器定制 5 浏览器默认最大化 xff0c 标题从配置文件读取 5 设置浏览器中文环境 xff0c 开启npapi插件功能 xff0c 并注册身份证阅