一卡通(iPASS)是與悠遊卡(EasyCard)都是台灣的電子票證智慧卡,二者都是使用RFID(菲利浦的MIFARE)技術。今天來分享大致的技術~
首先,您得先到一卡通官方網站中的”加入特約商店“,提供相關資料向一卡通票證公司申請,並向一卡通公司申請測試機器及卡片。
審核通過後,iPASS一卡通公司會提供一台一卡通的測試機器,以及相關的文件及SDK。SDK與之前刷卡系統神似~
主要是輸入長度62的in.txt;輸出的out.txt則為109~928(有無交易記錄)。
標籤: Delphi
餐飲POS新利器-取餐呼叫器與程式連線結合範例
在國外行之有年的取餐呼叫器(Pager)最近也在台灣風行起來,看到了二款取餐呼叫器,一個是國產亞克高科(ARCT)由銥特爾科技(02-29974000)代理,一個是韓國(Syscall)製造由鋐鈦科技代理。
二款都可以透過COM PORT設定~~ 以Delphi以及C#針對韓國的做範例。
Delphi
var iPagerno :Integer; sStr,s :AnsiString; begin Try Pager_COM.StopComm; // 先將Pager Com關閉 Pager_COM.CommName := ComName; Pager_COM.StartComm; Sleep(50); //開啟COM需等待 iPagerno := StrToIntDef(PagerNo,1); sStr := copy(IntToStr(iPagerno),1,4) s:= Ansichar(#開始指令)+sStr+Ansichar(#結束指令); Pager_COM.WriteCommData(PAnsiChar(s),Length(s)); Except End;
C#
public void Pager_Send(String COMName,String PagerNo) { public static System.IO.Ports.SerialPort PAGERPORT = new System.IO.Ports.SerialPort(); byte[] PAGERSTART = { 開始指令 }; byte[] PAGEREND = { 結束指令 }; try { if (PAGERPORT.IsOpen) PAGERPORT.Close(); PAGERPORT.PortName = COMName; PAGERPORT.BaudRate = 9600; PAGERPORT.Parity = System.IO.Ports.Parity.None; PAGERPORT.DataBits = 8; PAGERPORT.StopBits = System.IO.Ports.StopBits.One; PAGERPORT.Open(); if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PAGERSTART.Length; i++) { PAGERPORT.Write(PAGERSTART , i, 1); } PagerNo = PagerNo.PadLeft(4, '0').ToString(); byte[] PagerNoData= Encoding.Default.GetBytes(PagerNo); if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PagerNoData.Length; i++) { PAGERPORT.Write(PagerNoData, i, 1); } if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PAGEREND .Length; i++) { PAGERPORT.Write(PAGEREND , i, 1); } } catch { return; } }
POS系統介接與信用卡機連線的作法
Delphi或C#與信用卡連接的方式,有直接透過com port通訊或是透過呼叫exe的方式,利用in.txt、out.txt做溝通。然後回傳信用卡卡號/授權碼/刷卡金額等資訊。
示範一下Delphi與C#如何做信用卡線上刷卡。
Delphi
public { Public declarations } ExecInfo : TShellExecuteInfo; // use shellapi i:integer; end; procedure TForm1.Button1Click(Sender: TObject); var s:String; ts:TStringlist; begin ZeroMemory(@ExecInfo,SizeOf(ExecInfo)); with ExecInfo do begin cbSize := SizeOf(ExecInfo); fMask := SEE_MASK_NOCLOSEPROCESS; lpVerb := 'open'; lpFile := 'ecr.exe'; Wnd := self.Handle; nShow := SW_HIDE; end; s:='xxxxxxxxxxxxxxxxxxxx'; // 填上信用卡的溝通格式 ts := Tstringlist.Create; ts.Clear; ts.Add(s); ts.SaveToFile('in.dat'); ts.Free; ShellExecuteEx(@ExecInfo); deletefile('out.dat'); caption := '刷卡中...'; timer1.Enabled := True; i:=0; end; procedure TForm1.Timer1Timer(Sender: TObject); var ts1:Tstringlist; sstatus,smoney,scard,sappno:String; begin i:=i+1; if fileexists('out.dat') then begin Timer1.Enabled := false; ts1 := Tstringlist.Create; ts1.LoadFromFile('out.dat'); if ts1.Count >0 then begin // 讀入檔案,解析格式 end; ts1.Free; end; end;
string dir = System.Windows.Forms.Application.StartupPath; [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); private void uForm1_Load(object sender, EventArgs e) { try { if (File.Exists(dir + "/out.txt")) //刪除out.txt File.Delete(dir + "/out.txt"); string code = ""; // in.txt格式 using (StreamWriter sw = new StreamWriter(dir + "/in.txt")) //小寫TXT sw.Write(code); IntPtr PDC = FindWindow(null, "ecr"); //開啟PosDataCom if (PDC == (IntPtr)0) { try { Process p = new Process(); p.StartInfo.FileName = dir + "/ecrnccc.exe"; p.StartInfo.WorkingDirectory = dir; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); } catch (Exception exp) { return; } } this.timer1.Enabled = true; } catch (Exception ex) { throw new Exception(ex.Message); } } private void timer1_Tick(object sender, EventArgs e) { if (times == 5) { times = 0; i++; if (i > 4) { i = 0; try { if (File.Exists(dir + "/out.txt")) { using (StreamReader sr = new StreamReader(dir + "/out.txt")) //小寫TXT { String line; if ((line = sr.ReadLine()) != null) { // 解析 } else return false; return true; } } return false; } catch { return false; } } } times++; }
Delphi 10 Seattle隆重登場
Delphi透過odbc連結SQLite
Delphi5~7連接SQLite可以透過上述網站的SQLite ODBC Driver,透過ADO元件連結資料庫。
這樣一來,在開發行動裝置時。透過SQLite Expert建置完資料庫後,利用Delphi做資料整理~
再將資料放在Android 的asseets 或是iOS放在app document,core data初始化時再copy過去。
P.S Delphi 連線字串
DRIVER=SQLite3 ODBC Driver;Database=c:\test\test.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;
http://www.ch-werner.de/sqliteodbc/
Delphi XE3 下載JSON格式解析
DELPHI利用SUPEROBJECT以及INDY元件下載JSON格式做解析。
原始碼 https://github.com/superlevin/XE3JsonParser
程式下載 https://www.dropbox.com/s/bytp9vsxzht59fd/JSONParser.zip?dl=0
JAVA2OP更新
主要是修補缺少的二個檔案
bin\converters\java2op\bootclasses.jar
bin\converters\java2op\bootclasses.xml
下載之後將檔案copy到以下的路徑即可
bin\converters\java2op\bootclasses.jar
bin\converters\java2op\bootclasses.xml
Delphi 使用superobject分析JSON
http://superobject.googlecode.com
https://github.com/hgourvest/superobject
Delphi從2009才開始支援JSON格式,先前的版本需使用第三方函式庫才能解決。這邊提供不錯的SuperObject給大家。
使用方式很簡單,例如從台北市政府資料開放平台取得臺北市公廁點位資訊
[json]
[{“unit”:”台北市政府環境保護局”,”title”:”公廁坐落:士林官邸”,”dep_content”:”座數:8,特優級:2,優等級:6,普通級:0,加強級:0,無障礙設施”,”address”:”臺北市士林區福林路60號”,”lng”:”121.530152″,”lat”:”25.094898″,”modifydate”:”2013-03-25T17:58:20+08:00″},{“unit”:”台北市政府環境保護局”,”title”:”公廁坐落:天母公園”,”dep_content”:”座數
:1,特優級:0,優等級:1,普通級:0,加強級:0″,”address”:”臺北市士林區中山北路七段219號邊”,”lng”:”121.530071″,”lat”:”25.125855″,”modifydate”:”2015-08-06T00:00:00+08:00″}]
[/json]
[pascal]
uses superobject, supertypes, superxmlparser;
var vjson: Isuperobject;
vitem:Tsuperarray;
i,j:integer;
s:string;
begin
vjson:= so(‘[{"unit":"台北市政府環境保護局","address":"臺北市士林區福林路60號"},{"unit":"台北市政府環境保護局","address":"臺北市士林區中山北路七段219號邊"}]’);
vitem:=vjson.AsArray;
for i:=0 to vitem.Length-1 do begin
memo2.Lines.Add(vitem[i][‘unit’].AsString+’ ‘+vitem[i][‘address’].AsString);
end;
end;
[/pascal]
那如果格式如下
[json]
{“zoo”:”壽山動物園”,”animals”:[{“name”:”猴子”,”years”:”12″},{“name”:”猩猩”,”years”:”5″}]}
[/json]
[pascal]
var vjson: Isuperobject;
vitem:Tsuperarray;
i:integer;
begin
vjson:= so(‘{"zoo":"壽山動物園","animals":[{"name":"猴子","years":"12"},{"name":"猩猩","years":"5"}]}’);
memo2.lines.add(vjson[‘zoo’].asstring);
vitem:= vjson[‘animals’].AsArray;
for i:=0 to vitem.Length -1 do begin
memo1.Lines.Add(vitem[i][‘name’].AsString+’ ‘+vitem[i][‘years’].AsString );
end;
[/pascal]
Delphi XE8使用Microsoft Azure Translator微軟線上翻譯服務
在微軟的Microsoft Azure Marketplace有許多不錯的資料可以應用,今天就分享如果利用XE8搭配Microsoft Translator線上翻譯服務來做翻譯。
一、註冊Azure帳戶
點選 https://datamarket.azure.com/dataset/bing/microsofttranslator 上的登入,使用個人。然後依照步驗註冊就好。
二、訂閱服務
進入 https://datamarket.azure.com/dataset/bing/microsofttranslator ,點選2000000字元數/月的免費方案註冊。
三、註冊程式
程式中需要client_id跟client_secret ,所以到 https://datamarket.azure.com/developer/applications 註冊程式。
client_id就是用戶端識別碼
client_secret就是用戶端密碼
四、開始建立程式
新增一個Blank Application
接著在上面增加三個元件,TRESTClient、TRESTRequest跟TRESTResponse。重新命名為RESTClientAuthToken、RESTRequestAuthToken跟RESTResponseAuthToken.
RESTClientAuthToken的BaseURL設定 https://datamarket.accesscontrol.windows.net/v2
RESTRequestAuthToken的Method改為rmPOST、然後Resource設為OAuth2-13(參考 https://msdn.microsoft.com/en-us/library/hh454950.aspx)
然後在Params增加四個參數如下
在畫面上增加3個label、3個edit以及一個button
加上程式碼
[pascal]
var
token: string;
begin
RESTRequestAuthToken.Params.ParameterByName(‘client_secret’).Value := EditClient_Secret.Text;
RESTRequestAuthToken.Params.ParameterByName(‘client_id’).Value := EditClient_ID.Text;
RESTRequestAuthToken.Execute;
if RESTResponseAuthToken.GetSimpleValue(‘access_token’,token) then
begin
EditToken_value.Text := token;
end;
[/pascal]
取得Token值後我們可以開始進行翻譯,參考的文件為(https://msdn.microsoft.com/en-us/library/ff512387.aspx),一樣增加三個元件,TRESTClient、TRESTRequest跟TRESTResponse。重新命名為RESTClientTranslate、RESTRequestTranslate跟RESTResponseTranslate.。
RESTClientTranslate的BaseURL設為 http://api.microsofttranslator.com/v2/Http.svc
接著在RESTRequestTranslate的Resource設為Translate?text={text}&from={from}&to={to}
一樣在裡面增加四個Params,from跟to需要對應相關的語言代碼(參考https://msdn.microsoft.com/en-us/library/hh456380.aspx)
在畫面上增加combobox二個,以及二個memo及button。
開啟view→LiveBindings Designer,將RESTRequestTranslate中的Params.text指到Memo1的Text(輸入),然後RESTResponseTranslate.的Content指向Memo2的Text(輸出)。
最後補上翻譯的程式碼如下。
[pascal]
RESTRequestTranslate.Params.ParameterByName(‘Authorization’).Value := ‘bearer ‘+EditToken_value.Text;
RESTRequestTranslate.Params.ParameterByName(‘from’).Value := cbFrom.Selected.Text;
RESTRequestTranslate.Params.ParameterByName(‘to’).Value := cbToo.Selected.Text;
RESTRequestTranslate.Execute;
[/pascal]
番外篇:
語音的部份(參考 https://msdn.microsoft.com/en-us/library/ff512420.aspx)
增加一個RESTRequestPlay,然後設定Resource為 speak?text={text}&language={language}&to={to}&format=audio/mp3&options=MinSize 。
三個Param為 Authorization、text、language
以及增加mediaplayer。
程式如下
[pascal]
var
MS: TMemoryStream;
TempFile: string;
begin
RESTRequestPlay.Params.ParameterByName(‘Authorization’).Value := ‘bearer ‘+EditToken_value.Text;
RESTRequestPlay.Params.ParameterByName(‘language’).Value := RESTRequestTranslate.Params.ParameterByName(‘to’).Value;
RESTRequestPlay.Params.ParameterByName(‘text’).Value := RESTResponseTranslate.Content;
RESTRequestPlay.Execute;
MS := TMemoryStream.Create;
try
MS.WriteData(RESTResponsePlay.RawBytes,Length(RESTResponsePlay.RawBytes));
TempFile := TPath.ChangeExtension(TPath.GetTempFileName,’.mp3′);
MS.SaveToFile(TempFile);
MediaPlayer1.FileName := TempFile;
MediaPlayer1.Play;
finally
MS.Free;
end;
end;
[/pascal]
API參考
https://msdn.microsoft.com/en-us/library/dd576287.aspx
程式碼下載
https://drive.google.com/file/d/0BxMN7KkA7p3NZlU5clItaGxiMzQ/view?usp=sharing
原文:
http://blogs.embarcadero.com/stephenball/2015/06/30/using-azure-translator-services-with-delphi/
Embarcadero RAD Studio XE8, Delphi XE8, and C++ Builder XE8 Update 1 正式發佈
這次更新分為二種版本,分為有買維護合約且有效期的以及沒有買維護合約的版本。差別如下~
General Update 1 Feature and Fix List
This update is provided to XE8 customers without an Update Subscription
- Community toolbar
- iOS 8 simulator fix
- Several files missing from the initial XE8 delivery
Subscription Update 1 Features and Fix List
This update is provided to active Update Subscription customers
- Community toolbar
- Favorites in welcome page
- Fast search of Bluetooth LE devices
- iOS 8 simulator support
- Improved robustness of IDE productivity features
- Improvements in multi-device previews
延伸連結
Fix List for XE8 Update 1:
http://edn.embarcadero.com/article/44470