(39)uniGUI for CBuilder 掃描二維碼

                                                                                    (中行雷威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給我(羣主)留言。資料簡介:

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。

 

                                                                                 

 

控件名稱

屬性

取值

說明

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]

 

  1. 功能

系統啓動後直接調用主窗口MainmForm的OnReady事件初始化硬件設備,搜索設備共有幾個攝像頭,然後列舉出來,選擇一個後置攝像頭,點擊btnStart按鈕開始掃碼,對準條形碼或二維碼,滴的一聲將在下方的UnimMemo裏出現掃碼結果;點擊btnReset按鈕將停止掃描,可以重新選擇新的攝像頭,屏幕中如果同時出現一個條形碼和一個二維碼,將優先掃描二維碼。

3、代碼

1)UnimHTMLFrame1的HTML屬性代碼

<audio id="player" height="0px" src="files/beep-digital.mp3" style="display:none"></audio>

<div>

  <video id="video" width="100%" height="100%" style="border: 1px solid gray"></video>

</div>

 

<div id="sourceSelectPanel" style="display:none">

  <label for="sourceSelect">Change video source:</label>

  <select id="sourceSelect" style="max-width:400px">

  </select>

</div>

  1. UniServerModule的CustomFiles屬性代碼

files/zxing.min.js

 

3)UnimMain.cpp核心代碼

void __fastcall TMainmForm::UnimFormReady(TObject *Sender)

{

//初始化攝像頭

String tmpStr;

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);

}

 

void __fastcall TMainmForm::btnStartClick(TObject *Sender)

{//啓動掃碼

btnStart->JSInterface->JSCall("element.dom.click","[]");

}

//---------------------------------------------------------------------------

 

void __fastcall TMainmForm::btnResetClick(TObject *Sender)

{//停止掃碼

btnReset->JSInterface->JSCall("element.dom.click", "[]");

}

//---------------------------------------------------------------------------

 

void __fastcall TMainmForm::UnimHTMLFrame1AjaxEvent(TComponent *Sender, UnicodeString EventName,

         TUniStrings *Params)

{//Ajax回調獲取掃碼結果

if (EventName == "getResult" )

    {

    mResult->Lines->Add(Now());

    mResult->Lines->Add("【"+Params->Values["result"]+"】");//顯示掃碼結果

    UnimHTMLFrame1->JSInterface->JSCall("_ael.play", "[]");//滴滴一聲

    }

}

4、效果

設置手機,讓谷歌瀏覽器擁有攝像頭和聲音權限,打開手機的谷歌瀏覽器,輸入https://服務地址:8077,操作體驗一下吧(本案例在華爲和小米手機均調試通過,在PC版谷歌瀏覽器上測試時偶爾會出現攝像頭快速閃斷現象)。

       

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章