顯示具有 VCL friends 標籤的文章。 顯示所有文章
顯示具有 VCL friends 標籤的文章。 顯示所有文章

2016/11/17

加入 Windows Store 前的暖身‧使用 RAD Studio 10.1 Update 2


VCL 終於可以上 Windows Store 了嗎?

藉由微軟的【Desktop Bridge】,讓這件事情成為可能,RAD Studio 10.1 Update 2 打包了【Desktop Bridge】技術,讓使用 C++ Builder 和 Delphi 的開發者可以比使用 Visual Studio 更方便的轉換到 Windows Store。

教學無用,直接看熱身的結果吧!

2016/08/26

Delphi 免寫 FreeAndNil 的方法

好的 Free 帶你上天堂 (咦?) 圖片來源


最近看到一篇關於葡萄牙人寫的文章:FreeAndNil... Esqueça

內文是說明在物件導向的時代,JAVA、C# 這類的語言都有垃圾自動回收機制,進化中的 Delphi 其實也有。

接著便開始說明了使用 FreeAndNil 讓我們的原始碼非常噁心的經過。


提出的解法是使用 Interface!


原先我們的寫法可能是:

2016/08/19

泛型(Generic)容器的小技巧

泛型 (Generic) 是程式毒藥還是解藥? 圖片來源

在Delphi 2009開始便加入了【泛型容器】相關類別,如下所列:

  • TList,TObjectList
  • TQueue,TObjectQueue
  • TStack,TObjectStack
  • TDictionary,TObjectDictionary

不過也只知道可以放像是「string, Integer, TComponent」等,基本型別或是物件都可以自由宣告使用。

乍看下和 TStringList 重疊率很高啊,如果是宣告TList,居然不能使用以下的函式:
  • CommaText
  • DelimitedText 

不能用這兩個常用率特高的函式感覺很廢啊。泛型容器到底有什麼好用的?

一直到需要放置物件時,才開始覺得泛型容器超好用。


2016/08/12

[整理]如何計算出一個字元,在一個字串中出現的次數

字元(Char)計數
1
2
3
4
5
6
7
8
9
function OccurrencesOfChar(const S: stringconst C: char): integer;
var
  i: Integer;
begin
  result := 0;
  for i := 1 to Length(S) do
    if S[i] = C then
      inc(result);
end;



字串(String)計數
1
2
3
4
5
6
7
8
9
10
11
12
function Occurrences(const Substring, Text: string): integer;
var
  offset: integer;
begin
  result := 0;
  offset := PosEx(Substring, Text, 1);
  while offset <> 0 do
  begin
    inc(result);
    offset := PosEx(Substring, Text, offset + length(Substring));
  end;
end;

資料來源:

2016/05/24

IOUtils TDirectory.CreateDirectory 跳出 The drive cannot be found 錯誤

最近使用 IOUtils 單元的 TDirectory.CreateDirectory 來處理目錄建立的工作。

MSDN中說明這個函式的功能:
按照 path 所指定的來建立所有目錄和子目錄。

備註
會建立 path 中指定的任何和所有目錄,除非它們已經存在,或 path 的某些部分是無效的。path 參數指定的是目錄路徑,而不是檔案路徑。如果目錄已經存在,這個方法不執行任何動作。
所以DirectoryExists這類的工作都可以拿掉了,是個很方便的功能。

程式運作了好一陣子,都沒有出問題,一直到某天,客戶回傳了一個錯誤視窗:


於是,我又踏上抓鬼之路了。
  接著我請了個道士來 Debug   圖片來源


雖然已知是「TDirectory.CreateDirectory」造成的錯誤,但為什麼客戶會出現但我這裡完全沒事呢?


後來才知道,原來客戶的環境是以虛擬機器運作,以 UNC 路徑執行所有程式,看來就是 UNC 路徑搞的鬼。

What is "UNC"?就是像「\\ComputerName\DirectoryName」這樣的網路路徑。

總之,Bug找到了!讓我們來看看「它」長什麼樣子吧!



Bug 示意圖.........  圖片來源
































咳!………還是回到正題!


仔細研究原始碼,才發現在 IOUtils.pas 單元的函式出錯:
class procedure TDirectory.CheckCreateDirectoryParameters(const Path: string);

出錯的程式碼為:
if not TPath.DriveExists(TPath.DoGetPathRoot(Path)) then

因為沒有針對 UNC 路徑多做判斷,所以一定會跑「The drive cannot be found」錯誤。

找到了Bug,但要如何解決呢?很簡單,將出錯的那一列置換如下:
if TPath.IsDriveRooted(Path) and not TPath.DriveExists(TPath.DoGetPathRoot(Path)) then


如此便修正了這個問題,但最好是將底下路徑的IOUtils.dcu一併置換:
$(BDS)\lib\win32\debug
$(BDS)\lib\win32\release
$(BDS)\source\rtl\common


或是把 IOUtils.pas 複製到自己的專案進行修改後使用。


















最後,這個Bug在XE3之後已被修正。

See also:

2016/05/17

Delphi 加密解密(含數位簽章)的解決方案 -- 【初探篇】

嗯,今天不討論破解病毒的問題

一直以來,總是覺得自家系統的加密法很陽春,容易被破解,最近看到可怕的【 加密勒索病毒】,發現居然用到 RSA 4096 加密等級,凡是中招者,只能選擇「付贖金」或是「銷毀」這兩個選項。

看來這 RSA 加密真是個很可靠的東西,如果可以應用在自家的產品上……

2016/05/01

淺談 Delphi Class 和 Record Helper

Class (and Record) Helpers  圖片來源:Class Helper/Jobs Pictures

Helper 是一個從 Delphi 2005 開始就已經支援的特色之一。

使用時機:

在需要擴充現有Class或是Record裡的函式功能時使用之。

Delphi 7 之前我們要擴充或是修改現有Class功能時,我們會採取【基礎課程 - Delphi Interceptor Classes】這篇的作法。

然而在 Delphi 2005 之後,就可以利用 Helper 簡單作到對現有 Class 的擴充,以TStrings為例:我們在找尋字串是否在TStrings裡時,我們會用以下的判斷式:

2015/11/26

Delphi Web 開發解決方案:Kitto

Kitto 是款類似 UniGUI 的 Delphi 開發 Web 應用程式的解決方案之一。
Kitto Logo
先來看看它的架構:
Kitto 大略的架構

2015/11/03

FastReport在啟動時載入過久的問題

FastReport的Runtime Design模式很有意思。

幾乎快可以取代Delphi一大部份的功能。

不過有時會遇到報表檔載入時間很久很久的情形。

除了報表檔本身可能很大之外,在FR DataModule裡所存的DataSet,不過是在Design或是Runtime開啟時,也都會先Open!

就是那個Open!把整個啟動時間拉長了。


另外還有Design下設定好的TParams無法再設定的問題:
1.與Dialog視窗綁定的物件優先權較高
2.使用Design程式碼洗掉TDataSet重置

上述兩點都能解決TParams無法再設定的問題。

2015/07/27

Delphi字串計數函式

已經忘記是什麼時候遇到需要計算重複字的次數問題
前陣子想到才上Google來找,因為關鍵字仍然不方便搜尋,所以轉錄在這裡。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
uses
  StrUtils;

function Occurrences(const Substring, Text: string): Integer;
var
  offset: Integer;
begin
  result := 0;
  offset := PosEx(Substring, Text, 1);
  while offset <> 0 do
  begin
    inc(result);
    offset := PosEx(Substring, Text, offset + length(Substring));
  end;
end;

資料來源:

2015/07/21

TByte 和 TByteDynArray 的轉換

TByteDynArray 同等 TByte

意外發現 TBytesStream 這個類別

但發現不能做 TBytesStream.Create(TByteDynArray)
不過卻可以寫成這樣:
TBytesStream.Create(TByte(TByteDynArray))

據說後來有改正這個缺點。

see also:

2015/03/03

RAD Studio 2015 Roadmap

以下內容雖是正式內容,但EMBT不做任何保證。

平台和編譯器方面:
增加iOS 64位元編譯程式。
Windows 32位元的C++編譯器:
基於LLVM工具集,以近似於C++ 64位元版本編譯器特色(含C++11)。
(LLVM based toolchain similar to the 64-bit Windows compiler language features, including C++11)


寫程式的開發環境(IDE):
提高對大量記憶體的系統下,開發環境的穩定性。
整合Library管理功能。
主要增強FireUI對多平台裝置的設計,也包含其預覽功能。

Windows 10
具體支援Windows10:
VCL和FireMonkey。
新增許多元件和Library。
封裝更多的API。
整合新的Windows 10平台技術。

VCL和Run-Time Library:
改善VCL表現風格,支援4K螢幕、大型文字和其它增強。
提供VCL(含FireMonkey)應用程式分析。
提供原生HTTP(S)用戶端程式庫給全部平台。

FireMonkey
擴充FireMonkey控制項,包括:
新的行動裝置元件,如Maps。
被遺忘的元件,如WebBrowser。
更多iOS平台控制項和更佳的視圖層(z-order)管理器(iOS限定)。

物聯網
更貼近行動裝置的整合,預計支援Beacon技術。
基於元件形式的模組化以連接不同的裝置,和控制異質API的小工具。
遠程端點(裝置)的資料收集和分析。

企業和多層架構
FireDAC:新的企業級資料庫驅動程式以強化效能。
InterBase XE7變更視圖(Views)項目。
更緊密的整合EMS(Enterprise Mobility Services)。
NoSQL資料庫支援。
EMS:推播訊息和數個擴充。
DataSnap 在核心Web技術上的清理和改善。

其它平台下的了解和調查
觀注2015年iOS和Android的走向。
研究Web Service 應用程式(如WebBroker, DataSnap和EMS)對Linux伺服器站支援。
選擇性支援Android Intel平台。
Mac OS X 的64位元工具集。

預計第一季釋出新的版本和其它廢話。

大致上沒有太亮眼的功能。
以上

資料來源:Delphi & C++Builder 移動開發FB社群

2014/12/25

Devart UniDAC 和旗下的專用DAC 有何不同?

UniDAC 屬萬用型,各式資料庫都可以使用,但不支援資料庫 API

專用DAC,如 PgDAC, MyDAC, IbDAC 等,只支援其特定資料庫 (但 IbDAC 同時支援 Interbase 和 Firebird 兩種),支援直接連線 (Direct Connect) 和 API (如備份功能) 是其特色。

2014/10/17

Delphi 的四捨五入方法

Delphi 以往的「四捨六入五成雙」 -- Round
要改成常用的「四捨五入」,坊間有一大票使用很彆扭的方式來達成。

但 Delphi 的 Math 單元早已經有這樣的函式了:

Math.SimpleRoundTo

可是這樣的命名規則很不討喜,所以我們可以再重新封裝一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
uses
  Math;

function RoundA(A_Float: Extended): Integer; overload;
begin
  Result := Trunc(Math.SimpleRoundTo(A_Float, 0));  // 取整數部分即可
end;

function RoundA(A_Float: Extended; A_Digit: Integer=-2): Extended; overload;
begin
  Result := Math.SimpleRoundTo(A_Float, A_Digit);
end;

2014/10/06

溫習 RAD Studio 各個版本新增的內容

很好奇每個版本間到底有什麼差異,把 HELP 的連結貼過來,方便溫習。

What Was New in Past Releases


底下是個人筆記重點:
===========================================

2007 Add:

dbExpress 系:

  • Driver 最佳化。
  • Driver 增加部份對資料庫的 Unicode 支援。(但 VCL UI 元件還不支援 Unicode,白搭)

RTL 系:

TFileOpenDialog, TFileSaveDialog, TTaskDialog:
但這些都是 Vista (含以上) 限定, XP 以下不工作。

TTaskDialog 畫面很漂亮!學習資料:

其它新增的類別大都是為了上述元件產生的。
==================================

2009 Add:

DataSnap 系:

  • 基於 Indy 的 TDSxxx 元件,所做出的 RESTful 框架。(Base WinHTTP)
  • 納入 Blackfish 資料庫 ($$$)。

RTL 系:

  • 正式導入 Unicode
  • 增加更多的 UI 元件。如:Tiburon 和 Ribbon
  • 改變 TDataSet.Bookmark 的方法
  • 因應 GlyFx 而增加的單元: PNG = pngimage; Gif = gifImg; Jpg = jpeg ← 超重要
==================================

2010 Add:

IDE 最佳化。

DataSnap 系:

  • 提供 MIDAS DLL 的原始碼。
  • 強化 RESTful 框架。

RTL 系:

  • 增加 RTTI 單元。
  • 增加支援平板的 手勢、 Touch 功能。
  • 重製 .NET: TStringBuilder 元件在 RAD Studio 上。
  • 新增的元件 Bug 修正和補強。
==================================

XE Add:

Blackfish 死掉了。

IDE 增加 Code Formatting 功能,終於可以自動化編排原始碼了。
Code Editor 強化了許多功能和樣版(Live Templates)。大推

DataSnap 系:

  • 持續增強 RESTful 框架,並加強 dbExpress 對 JSON 的支援。

RTL 系:

  • 增加 IOUtils 單元。
  • TStrings 加入 TEncoding 初始化功能。
  • 加入一票 3rd 函式庫;如:RegularExpressions、Boots 等。
  • TThread.Suspend 和 Resume 被刪除了,新的使用方式請詳閱公開說明書。
  • C++ VCL 增加了對 Unicode 的支援。

消化完再走到下一版。

XE7 Add:


    2014/09/10

    淺談協調者模式[Mediator Pattern] - 使用 Delphi + Interface

    在「深入淺出-設計模式」一書中談到「居間協調者模式」時,把它歸類在不受設計人歡迎的模式中(請參閱:14 附錄:剩下的模式-居間協調者模式)。

    只是,它有提到在 MVC 中經常會使用這個模式來設計。看了下它的介紹,就真的是簡短到一個極致。

    接著便拿起「參悟物件設計模式 - 使用 Delphi」一書,翻到了「協調者模式」一節。

    ……還是有點難理解,按本人羸弱的思考能力是這樣解讀的:

    2014/09/01

    淺談策略模式[Strategy Pattern] - 使用 Delphi + Interface



    Delphi 這麼久,Class 一直都是我愛用的關鍵字之一。
    在看了 Code in Delphi 之後,還是不了解為什麼要使用 Interface

    於是又看了下 Head First Design Patterns (深入淺出設計模式) 的第一章。

    按照我現在只會的物件導向概念,在鴨子類別及實體的設計,大概會長成這樣:

    2014/07/29

    [DateUtils]查出指定時間的當月第一天和最後一天

    突然有這樣的一個需求,上網查了一下發現很大一票的高手在這塊都自己刻一份副程式。

    難道 VCL Framework 裡就沒有好用的函式可使嗎?

    答案是:有的

    EndOfAMonth in Delphi Basics 中有提到了我想要的東西。

    在 DateUtils 裡有「StartOfTheMonth」和「EndOfTheMonth」這兩個函式,可以很輕鬆地取得指定時間的 1 號 和 28.29.30.31 的最末日

    範例如下:
    var
      vFirstDate, vLastDate: TDateTime;
    begin
      vFirstDate := DateUtils.StartOfTheMonth(Now());
      vLastDate   := DateUtils.EndOfTheMonth(Now());
      ShowMessage('The Month first Date: ' + DateToStr(vFirstDate) + #13#10 +
                  'The Month last Date: ' + DateToStr(vLastDate));
    



    只是,按「易讀程式之美學」一書所建議的起始和最末範圍命名法則有點小小的衝突,
    ==============
    Start → First
    End → Last
    ==============
    但因為不會有「32」日這種超出日期的可能,這種小缺點就忍耐一下吧 (笑)


    2014/07/15

    TDataSet.OnValidate 和 OnChange 事件使用心得

    OnValidate:
      單純的檢查事件,在這個事件中無法對 Sender(TField) 進行改值。


    OnChange:
      接在 OnValidate 事件後觸發,值的變更可在此事件中處理。

    2014/02/21

    DsnDBCst.dcu 找不到的問題

    DsnDBCst 是 DSDesign 元件中的檔案之一。

    但在 Delphi 7 之後就找不到這個檔案了,所以在編譯舊元件時可能會出錯。
    而且也找不到這個神奇元件在哪邊。

    所幸,萬能的 Google 大神引領我,找到了替代品
     「VclDesigner」

    將原有的 uses DsnDBCst 拿掉,並且引入 VclDesigner 到 Package 的 Requires 區,如此一來就可以了。

    但可能編譯時,還是會失敗。

    實際看過網路上流傳的 DsnDBCst.pas 後,才發現原來這個檔案的功用,有一半的功能是做 ResourceString 映射功能,如果有需要也可以自己補在需要出現的地方。

    See Also:
    [Pascal Fatal Error] DSDesign.pas(18): F1026 File not found: 'DsnDBCst.dcu'
    kbmMemTable missing DSDesign.dcu
    DsnDBCst为何物?