2015年12月7日 星期一

Lazarus 系列–4. 連接資料庫

在 Lazarus 的世界裡,沒有 BDE、ADO、dbExpress 等 Delphi 世界裡的資料庫連接方式,內建的是 SQLdb。除了 SQLdb 之外,有一些第三方的資料庫元件廠商也推出了給 Lazarus 使用的連接元件,今天不談第三方元件,專談 SQLdb。

SQLdb 支援的範圍很廣,涵蓋了經常使用的各種資料庫,包括 MSSQL、MySQL、SyBase、PostgreSQL、Oracle、Interbase、SQLite 等,如果超過這些資料庫的範圍,還可以用 ODBC 來連接。而 SQLdb 的底層呼叫的則是各家資料庫提供的原生連接函式庫 (MSSQL 除外,底下會詳細說明)。

底下這張圖是 SQLdb 元件盤上的元件,其實可以完全只用前四個,後面的大多是各家資料庫專屬的連線元件以及管理元件,如果只需要做 CRUD 就可以不用管那些元件,而 CRUD 這四個動作幾乎已經涵蓋資料庫操作的 9 成以上了。

2015-12-06_023943

前四個元件由左而右分別是:

  1. SQLQuery:處理 CRUD 主要的元件
  2. SQLTransaction:處理 transaction 的元件,必要
  3. SQLScript:執行 SQL script 的元件
  4. SQLConnector:連接資料庫的元件,必要

其他的元件說明就請參照官網了。

 

剛才說到,SQLdb 的底層呼叫的是各家資料庫提供的原生連接函式庫,以在 Windows 平台上的 PostgreSQL 為例,呼叫的是 libpq.dll,一個比較方便的方法是下載 [easy_db_plus.zip],這是一個 demo 連結 PostgreSQL 的程式,解開之後,把所有的 dll 檔複製進 Lazarus 的安裝目錄以及你的專案目錄就可以了。

而 MSSQL 的狀況則不同,SQLdb 呼叫的並不是原生的 SQL Server Native Client,而是 dblib.dll,到 [這裡] 下載 dblib_current.zip 並解壓縮之後,將 dblib_XXXX.dll 以及 libiconv2.dll 複製進 Lazarus 的安裝目錄以及你的專案目錄,然後將 dblib_XXXX.dll 改名為 dblib.dll 就可以了。
(看你要連那一個版本的 MSSQL,目前是到 dblib_2008.dll,拿這個連 MSSQL 2012 也可以的)

 

接下來就以 MSSQL 為例子示範如何連接資料庫,並完成一個簡單的 CRUD 應用程式

  1. 放一個 SQLTransaction
  2. 放一個 SQLConnector,設定以下屬性:
    • Transaction 設定為 SQLTransaction1
    • ConnectorType 設定為 MSSQLServer
  3. 放一個 SQLQuery,設定以下屬性:
    • Database 屬性設定為 SQLConnector1,這時你可以觀察到 SQLQuery.Transaction 屬性也自動的被設定為 SQLTransaction1
    • PacketRecords 屬性設定為 -1 (MSSQL必須,其他資料庫可保持為預設值 10)
  4. 放一個 DataSource,設定以下屬性:
    • 設定 DataSet 屬性為 SQLQuery1
  5. 放一個 DbGrid,設定以下屬性:
    • 設定 DataSource 屬性為 DataSource1
  6. 放一個按鈕,撰寫 OnClick 事件如下:

    // 請將黃色字替換成你實際要用的值,可用 :port 來指定 MSSQL 偵聽的 port 號
    SQLConnector1.Close;
    SQLConnector1.HostName := '127.0.0.1';   
    SQLConnector1.DatabaseName := 'DB1';
    SQLConnector1.UserName := 'username';
    SQLConnector1.Password := 'password';
    SQLConnector1.Open;
    SQLQuery1.SQL.Text := 'SELECT * FROM TABLE1';
    SQLQuery1.Open;
  7. 編譯,執行,按下 Button1,若順利的話,可以看到 DbGrid 出現資料。如果出現連接失敗的訊息,請檢查 MSSQL 是否開啟了 TCP/IP 連線,以及 TCP 偵聽的 port 號

剛才完成的只有 CRUD 中的 R,接下來繼續完成 CUD 三部分

  1. 再放一個按鈕,撰寫 OnClick 事件如下:

    try
      SQLQuery1.ApplyUpdates;
      SQLTransaction1.CommitRetaining;
    except
      SQLTransaction1.RollbackRetaining;
      SQLQuery1.CancelUpdates;
    end;
  2. 編譯,執行,按下 Button1,在 DbGrid 上做新增、修改、刪除等動作,然後按 Button2,再去檢查資料,就發現資料已經異動了。
  3. 這種方法必須仰賴 table 本身有 primary key,才能正確的做出異動動作

但是如果 table 沒有 primary key,要如何做呢?SQLQuery 除了 SQL 屬性之外,還有 InsertSQL、UpdateSQL、DeleteSQL 三個屬性,請分別給這三個屬性設定正確的新增、修改、刪除的 SQL 敘述,參數部分用 : 開頭,原值參數用 :OLD_ 開頭 (必須是大寫)

需要更詳細的說明,請參閱 [官網]

這一期就講到這裡,下期再見

2015年11月18日 星期三

Lazarus 系列–3. Canvas 的使用

這一集用一個小程式來示範 Canvas 的使用,這個程式很簡單,就是用來模擬一種玩具「萬花尺

基本上,就是依據不同的參數畫出以下函數的圖形:

x := r1 * cos(θ * t1) + r2 * cos(θ * t2)
y := r1 * sin(θ * t1) + r2 * sin(θ * t2)

r1 = 大圓半徑,r2 = 小圓半徑
t1 = 大圓轉圈的速度,r2 = 小圓轉圈的速度

底下是幾個輸出的範例圖形

001

002

原始程式碼 在這裡下載,請大家自己研究一下囉

2015年11月4日 星期三

Lazarus 系列–2. 視窗畫面的佈局

Lazarus LCL 元件組的佈局,跟 VCL 很相似。為什麼說「很相似」呢?是 Lazarus 的 LCL 元件提供比 VCL 還要多,可以更方便的做好畫面的佈局。

 

一、Align 屬性:這個屬性指定了元件在 parent 中「怎麼靠邊」有以下幾種:

  • alTop:往上靠
  • alBottom:往下靠
  • alLeft: 往左靠
  • alRight:往右靠
  • alClient:填滿中間
  • alNone:都不靠
  • alCustom:這個不明白他怎麼靠,反正不是靠北靠木就是了 (VCL 沒有這個)

  來張圖就更清楚了 (為了方便看清楚 panel 的邊界,把每一個 panel 的 BevelWidth 屬性設定為 5)
2015-11-04_075758

  善用 Align 屬性可以很方便的給畫面佈局「切版」。

 

二、Anchors 屬性:Anchor 就是船錨,這個屬性用來指定元件在 parent 中「哪幾個邊要與 parent 同方向的邊保持固定距離」(以下稱為設定錨點),有以下幾種,均可以分別開啟與關閉:

  • akTop:上方保持固定距離,預設開啟
  • akBottom:下方保持固定距離
  • akLeft:左方保持固定距離,預設開啟
  • akRight:右方保持固定距離

來兩張圖示範一下效果

Panel1 把四個 Anchors 屬性都打開了,然後把 form 拉大,Panel1 的四個邊界依然與 form 的邊界保持固定距離。

2015-11-04_082421

2015-11-04_082852

Lazarus 的 Anchors 屬性除了把錨點設定在 parent 上以外,還可以把錨點設定在不是 parent 的元件上,還可以設定錨定時如何對齊,錨定時要留多少距離

2015-11-04_203829

這是 LCL 的錨點設定視窗,可以看到每一個方向都有 4 個設定項目:

  • Enabled:是否開啟這個方向的錨點
  • Sibling:我的兄弟是誰,就是我要跟誰錨定
  • 三個按鈕:如何對齊,有「對齊邊界」「依序排列」「對齊中線」三種
  • Border space:對齊邊界或是依序排列時要空出多少寬度

打個比方,將 Edit1 做如下的錨點設定之後,移動 Label1 時,Edit1 就會跟著移動:

2015-11-04_204701

Edit1 的上邊界與 Label1 錨定,對齊中線,同時左方也與 Lable1 錨定,依序排列,中間間隔 5px,這樣設定的結果如下圖:

2015-11-04_204911

把 Label1 抓著移動時,Edit1 會跟著移動,但是 Edit1 就無法被抓著移動了:

2015-11-04_204926

 

三、ChildSizing 屬性,這是容器元件才有的屬性,用來規範自己內部的元件要如何排列

2015-11-04_205231

  • ControlsPerLine:一列要排幾個元件
  • EnlargeHorizontal:自己被拉寬時,內部元件的寬度要如何變化
  • EnlargeVertival:自己被拉高時,內部元件的高度要如何變化
  • HorizontalSpacing:內部元件的水平間距
  • Layout:要怎麼排列內部元件
  • LeftRightSpacing:排列時,左右要空多少不拿來排列內部元件,就相當於 CSS 的 padding-left 與 padding-right
  • ShrinkHorizontal:自己被拉窄時,內部元件的寬度要如何變化
  • ShrinkVertival:自己被拉矮時,內部元件的高度要如何變化
  • TopBottomSpacing:排列時,上下要空多少不拿來排列內部元件,就相當於 CSS 的 padding-top 與 padding-bottom
  • HorizontalSpacing:內部元件的垂直間距

拿兩張圖來示範一下排列前與排列後,隨意擺放幾個元件,準備來排列

2015-11-04_205845

接下來,設定 Form1 的 ChilldSizing 屬性以及這些元件的 Z-Order 如下:
(設定 Z-Order 可以在 form 上選擇一個元件,然後使用 Ctrl-PgUp 與 Ctrl-PgDn 這兩個熱鍵來調整)

2015-11-04_210238

2015-11-04_210252

然後,這些元件就排列好了:

2015-11-04_210629

將 form 改變大小試試:

2015-11-04_210733

2015-11-04_210741

很方便,對吧!
可惜有一點,一個元件固定佔用一個「格子」,沒辦法跨列、跨欄,不過已經非常方便了!

這一篇就講到這裡,我們下期再見!

2015年11月1日 星期日

Lazarus 系列–1. 環境簡介

Lazarus 是一個 Open Source、跨平台的 Free Pascal 整合開發環境,可以稱得上是 Delphi 的 open source 替代品。詳細的歷程就請大家自行前往 Wiki官網 收看,這裡就不再多說了。

這一篇是介紹 Lazarus 的安裝與開發環境的巡覽

 

一、安裝

官網的下載頁 依據您的環境下載適當的版本,在 Windows 上安裝很簡單,就是下一步下一步而已,Linux 的使用者可能就稍微複雜一點,不同的發行版的安裝方式可能會有些不同。

安裝完成之後,首次執行會檢查必要的組件是否安裝,Windows 版本就不用煩惱,一定是全部都安裝好的,Linux 版本就要看一下了,可能要補安裝一些必要組件

 

二、開發環境巡覽

2015-11-01_214911

看到這個畫面,用過老版本 Delphi (D7及以前) 的人一定感到很親切,幾乎是一模一樣的嘛!接下來一個個視窗來說明

  1. 主功能表、工具列與元件盤
  2. 物件檢視器 Object Inspector
    顯示及修改目前選取到的物件的屬性、事件
  3. 專案檢視器 Project Inspector
    顯示專案的結構
  4. 程式碼編輯器 Source Editor
    這裡當然就是編輯程式碼的地方
  5. 訊息視窗 Messages
    顯示編譯輸出、錯誤訊息的地方
  6. 畫面設計視窗
    用拖拉方式來設計畫面的地方

看起來跟老版本 Delphi 幾乎都一樣,是吧!接下來說說跟 Delphi 不一樣的地方

  1. 可以編譯出 x86 與 x64 的應用程式,不過得安裝兩套,而且必須安裝在不同的目錄
  2. 原生支援 Unicode
  3. 程式碼編輯器採用的是 SynEdit 元件,比起 Delphi 的程式碼編輯器有蠻大的進步
  4. 程式碼的副檔名不同 dpr –> lpr、dfm –> lfm,故無法直接開 Delphi 的程式來編譯,必須經過轉換
  5. 熱鍵可以更改,也就是 Ctrl-Space 這個最常用的熱鍵可以改成別的,我個人是改成 Alt-Right (與 Visual Studio 相同)
  6. VCL 元件不是 100% 對應過來的,有些元件在 Lazarus 沒有,反之亦然
  7. 資料庫存取相關元件方面,沒有 BDE、ADO、dbExpress、FireDAC,也沒有 DataSnap,Lazarus 有一套自己的,叫做 SQLdb,支援的資料庫有 MSSQL、Sybase、MySQL、PostgreSQL、Firebird (Interbase)、Oracle、ODBC 和 SQLite,市面上常見的可以說都支援了。
  8. 對於檔案型資料庫的支援有 DBF、CSV、SDF(沒用過這個)、以及固定長度格式
  9. 安裝 package 必須重新編譯 Lazarus 開發環境
  10. 市面上的 3rd party 元件組,通常在 Lazarus 上不可用
  11. 其他還有很多,就請大家自己去發現了!

總之,要拿 Lazarus 來寫一些自己用的小程式,是完全可行的。如果要拿來寫商用軟體,則需要很大的努力,如果抱著「為什麼 Delphi 可以 Lazarus 不行」這樣的心態來對待 Lazarus,那就直接用 Delphi 就好了,不是嗎?

 

附記一:程式碼編輯器在 Linux 環境無法輸入中文的臨時解決方法

程式碼編輯器在 Linux 環境無法輸入中文,有一個勉強還可以接受的方法是按 Ctrl-Alt-T 熱鍵插入「ToDo」,輸入完之後再把
{ TODO : } 刪除掉
2015-11-01_220005

按下 OK 之後,就成了這樣
2015-11-01_220042

2015年5月12日 星期二

用 ZXing 製作帶有中文的 QRCode

ZXing 是一個一維/二維條碼製作與識別的 library,計畫首頁在 https://github.com/zxing
本文要說的是如何製作帶有中文的 QRCode。不用囉唆了,直接看 code

using ZXing;
using ZXing.Common;
using ZXing.QrCode;
using ZXing.QrCode.Internal;

IBarcodeWriter writer = new BarcodeWriter()
{
    Format = BarcodeFormat.QR_CODE,
    Options = new QrCodeEncodingOptions()
    {
        ErrorCorrection = ErrorCorrectionLevel.M,
        Margin = 0,
        Width = 150,
        Height = 150,
        CharacterSet = "UTF-8"   // 少了這一行中文就亂碼了
    }
};

Bitmap bm =
    writer.Write(“腦殘賤貓的備忘錄 http://maolaoda.blogspot.tw/”);


這樣就得到了一個 QRCode 圖片

image

簡單吧!