目录
目录... 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
一、工具准备
- vs 2017 community
- cmake 3.7 +
- 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(使用前将#替换为@)