(39)uniGUI for Delphi 扫描二维码

                                                                                 (中行雷威2020.05.21)

(同一个世界,同一个梦想,交流学习C++Builder and Delphi XE10,传承c++builder and Delphi的魅力!欢迎各地朋友加入我的QQ群484979943,进群密码“BCB”,同时也请将该群号广为宣传,希望能够广集各方高手,共同进步。如需下载开发工具及源代码请加入我的QQ群。)

【阅读倡议】

1、有问题请留言;

2、没问题请点赞;

3、看连载请加群;

4、下源码请加群;

【开发工具】

1、C++Builder and Delphi 10.3.3

2、FMSoft_uniGUI_Complete_Professional_1.70.0.1531(正版)

本人主笔的国内第一本uniGUI教学案例代码已诞生,分为cbuilder和delphi两个版本,买代码送教程,需要的朋友可以加入我的QQ技术交流群484979943给我(群主)留言。资料简介:

(39)uniGUI for Delphi 扫描二维码_第1张图片

https://www.meipian.cn/20b86ayo?share_from=others&user_id=64168117&uuid=a8a75af8c0cc31e6a21b8a79a2b07398&share_depth=1&first_share_uid=64168117&utm_medium=meipian_android&share_user_mpuuid=94b70e99e8b6986c71b270a9883befb2

1.1手机扫描二维码

UniGUI目前(截至1525版本)还没有自己的扫码控件,但是它最大的特点就是打通了对JavaScript的调用,可以调用第三方的js实现扫码,本例将调用ZXing扫码的js代码实现移动设备扫码,它既是一个扫码案例,又是一个详细阐释uniGUI如何调用JavaScript和回调的案例。

1、布局

新建一个项目,配置好并保存项目,然后编译运行项目,生成输出目录结构,然后将本节配套代码files目录下的beep-digital.mp3(扫码声音文件)和zxing.min.js(ZXing的JavaScript文件)复制到Win32\Debug\files目录下;因为ZXing扫码使用了https加密连接,需要SSL证书和SSL库文件,将tools目录下的cert.pem、key.pem、root.pem(SSL证书文件)、libeay32.dll、ssleay32.dll(SSL驱动文件)复制到Win32\Debug目录下(证书文件的生成及https连接的使用方法详见我的《UniGUI入门到精通》教程的“加密连接”章节)。

在MainmForm上添加一个UnimHTMLFrame、两个UnimButton和一个UnimMemo。UnimHTMLFrame1用来关联ZXing的js脚本实现摄像头选择和摄像头扫码;UnimButton一个用来启动扫码,命名为btnStart,一个用来停止扫码,命名为btnStop;UnimMemo1用来记录扫码结果,命名为mResult。

 

                                                                         (39)uniGUI for Delphi 扫描二维码_第2张图片

 

控件名称

属性

取值

说明

UnimHTMLFrame1

Align

alTop

 

 

AlignWithMargins

TRUE

保留控件四周边界

btnStart(UnimButton1)

Align

alTop

 

 

AlignWithMargins

TRUE

保留控件四周边界

btnReset(UnimButton2)

Align

alTop

 

 

AlignWithMargins

TRUE

保留控件四周边界

mResult(UnimMemo1)

Align

alTop

 

 

AlignWithMargins

TRUE

保留控件四周边界

UniServerModule

CustomFiles

files/zxing.min.js

调用Zxing JS代码

 

FilesFolder

files\

默认文件目录

 

SSL->Enabled

TRUE

启动SSL

 

SSL->Password

8077

HTTPS端口

 

SSL->CertFile

cert.pem

证书文件及配置

 

SSL->KeyFile

key.pem

 

SSL->Method

sslvTLSv1_1

 

SSL->Mode

sslmUnassigned

 

SSL->RootCertFile

root.pem

 

SSL->Versions

[sslvTLSv1_1]

2、功能

系统启动后直接调用主窗口MainmForm的OnReady事件初始化硬件设备,搜索设备共有几个摄像头,然后列举出来,选择一个后置摄像头,点击btnStart按钮开始扫码,对准条形码或二维码,滴的一声将在下方的UnimMemo里出现扫码结果;点击btnReset按钮将停止扫描,可以重新选择新的摄像头,屏幕中如果同时出现一个条形码和一个二维码,将优先扫描二维码。

3、代码

1)UnimHTMLFrame1的HTML属性代码

 

 

2)UniServerModule的CustomFiles属性代码

files/zxing.min.js

 

3)UnimMain.pas核心代码

    procedure btnInitClick(Sender: TObject);//定义摄像头初始化函数

    procedure btnStartClick(Sender: TObject);//开始扫码事件

    procedure btnResetClick(Sender: TObject);//停止扫码事件

    …

 

//初始化摄像头清单, 让MainmForm的OnReady事件直接调用btnInitClick函数

procedure TMainmForm.btnInitClick(Sender: TObject);

var

  tmpStr:String;

begin

tmpStr:=UnimHTMLFrame1.JSName +'._ael=document.getElementById("player");'+ UnimHTMLFrame1.JSName +'._ael.load();'+

  UnimHTMLFrame1.JSName + '.oldResultText="";'+

  'let selectedDeviceId;'+

  '    const codeReader = new ZXing.BrowserMultiFormatReader();'+

  '    codeReader.getVideoInputDevices()'+

  '      .then((videoInputDevices) => {'+

  '        const sourceSelect = document.getElementById("sourceSelect");'+

  '        selectedDeviceId = videoInputDevices[0].deviceId;'+

  '        if (videoInputDevices.length >= 1) {'+

  '          videoInputDevices.forEach((element) => {'+

  '            const sourceOption = document.createElement("option");'+

  '            sourceOption.text = element.label;'+

  '            sourceOption.value = element.deviceId;'+

  '            sourceSelect.appendChild(sourceOption);'+

  '          });'+

 

  '          sourceSelect.onchange = () => {'+

  '            selectedDeviceId = sourceSelect.value;'+

  '          };'+

 

  '          const sourceSelectPanel = document.getElementById("sourceSelectPanel");'+

  '          sourceSelectPanel.style.display = "block";'+

  '        }'+

 

  '        document.getElementById("'+ btnStart.JSId +'").addEventListener("click", () => {'+

  '          codeReader.decodeFromVideoDevice(selectedDeviceId, "video", (result, err) => {'+

  '            if (result&&result.text!='+UnimHTMLFrame1.JSName+'.oldResultText) {'+

  '              window.ajaxRequest('+ UnimHTMLFrame1.JSName +', "getResult", ["result="+result.text]);'+

                 UnimHTMLFrame1.JSName + '.oldResultText=result.text;'+

  '            }'+

  '            if (err && !(err instanceof ZXing.NotFoundException)) {'+

  '            }'+

  '          });'+

  '        });'+

  '        document.getElementById("'+ btnReset.JSId +'").addEventListener("click", () => {'+

  '          codeReader.reset();'+

  '          ajaxRequest('+ UnimHTMLFrame1.JSName +', "getResult", ["result="+""]);'+

  '        })'+

  '      })'+

  '      .catch((err) => {'+

  '        alert(err)'+

  '      })';

  UniSession.AddJS(tmpStr);

end;

 

//停止扫码

procedure TMainmForm.btnResetClick(Sender: TObject);

begin

  (Sender as TUnimButton).JSInterface.JSCall('element.dom.click', []);

end;

 

//开始扫码

procedure TMainmForm.btnStartClick(Sender: TObject);

begin

  (Sender as TUnimButton).JSInterface.JSCall('element.dom.click', []);

end;

 

//UnimHTMLFrame的OnAjaxEvent事件实现Ajax回调传回扫码结果

procedure TMainmForm.UnimHTMLFrame1AjaxEvent(Sender: TComponent;

  EventName: string; Params: TUniStrings);

begin

  if (EventName = 'getResult') and (Params.Values['result']<>Trim(mResult.Text)) then

  begin

    mResult.Lines.Add(FormatDateTime('yyyyMMdd hh:nn:ss',Now()));

    mResult.Lines.Add('【'+Params.Values['result']+'】');

    UnimHTMLFrame1.JSInterface.JSCall('_ael.play', []);

  end;

 

end;

 

initialization

  RegisterAppFormClass(TMainmForm);

 

end.

4、效果

设置手机,让谷歌浏览器拥有摄像头和声音权限,打开手机的谷歌浏览器,输入https://服务地址:8077,操作体验一下吧(本案例在华为和小米手机均调试通过,在PC版谷歌浏览器上测试时偶尔会出现摄像头快速闪断现象)。

(39)uniGUI for Delphi 扫描二维码_第3张图片  (39)uniGUI for Delphi 扫描二维码_第4张图片  (39)uniGUI for Delphi 扫描二维码_第5张图片

   

你可能感兴趣的:(C++,Builder(uniGUI,移动开发),unigui,扫码,二维码)