

一卡通(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
















