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)計數
字串(String)計數
資料來源:
1 2 3 4 5 6 7 8 9 | function OccurrencesOfChar( const S: string ; const 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中說明這個函式的功能:
程式運作了好一陣子,都沒有出問題,一直到某天,客戶回傳了一個錯誤視窗:
於是,我又踏上抓鬼之路了。
雖然已知是「TDirectory.CreateDirectory」造成的錯誤,但為什麼客戶會出現但我這裡完全沒事呢?
後來才知道,原來客戶的環境是以虛擬機器運作,以 UNC 路徑執行所有程式,看來就是 UNC 路徑搞的鬼。
What is "UNC"?就是像「\\ComputerName\DirectoryName」這樣的網路路徑。
總之,Bug找到了!讓我們來看看「它」長什麼樣子吧!
咳!………還是回到正題!
仔細研究原始碼,才發現在 IOUtils.pas 單元的函式出錯:
出錯的程式碼為:
因為沒有針對 UNC 路徑多做判斷,所以一定會跑「The drive cannot be found」錯誤。
找到了Bug,但要如何解決呢?很簡單,將出錯的那一列置換如下:
如此便修正了這個問題,但最好是將底下路徑的IOUtils.dcu一併置換:
$(BDS)\lib\win32\debug
$(BDS)\lib\win32\release
$(BDS)\source\rtl\common
或是把 IOUtils.pas 複製到自己的專案進行修改後使用。
最後,這個Bug在XE3之後已被修正。
See also:
MSDN中說明這個函式的功能:
按照 path 所指定的來建立所有目錄和子目錄。所以DirectoryExists這類的工作都可以拿掉了,是個很方便的功能。
備註
會建立 path 中指定的任何和所有目錄,除非它們已經存在,或 path 的某些部分是無效的。path 參數指定的是目錄路徑,而不是檔案路徑。如果目錄已經存在,這個方法不執行任何動作。
程式運作了好一陣子,都沒有出問題,一直到某天,客戶回傳了一個錯誤視窗:
於是,我又踏上抓鬼之路了。
雖然已知是「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
2015/11/03
FastReport在啟動時載入過久的問題
FastReport的Runtime Design模式很有意思。
幾乎快可以取代Delphi一大部份的功能。
不過有時會遇到報表檔載入時間很久很久的情形。
除了報表檔本身可能很大之外,在FR DataModule裡所存的DataSet,不過是在Design或是Runtime開啟時,也都會先Open!
就是那個Open!把整個啟動時間拉長了。
另外還有Design下設定好的TParams無法再設定的問題:
1.與Dialog視窗綁定的物件優先權較高
2.使用Design程式碼洗掉TDataSet重置
上述兩點都能解決TParams無法再設定的問題。
幾乎快可以取代Delphi一大部份的功能。
不過有時會遇到報表檔載入時間很久很久的情形。
除了報表檔本身可能很大之外,在FR DataModule裡所存的DataSet,不過是在Design或是Runtime開啟時,也都會先Open!
就是那個Open!把整個啟動時間拉長了。
另外還有Design下設定好的TParams無法再設定的問題:
1.與Dialog視窗綁定的物件優先權較高
2.使用Design程式碼洗掉TDataSet重置
上述兩點都能解決TParams無法再設定的問題。
2015/07/27
Delphi字串計數函式
已經忘記是什麼時候遇到需要計算重複字的次數問題
前陣子想到才上Google來找,因為關鍵字仍然不方便搜尋,所以轉錄在這裡。
資料來源:
前陣子想到才上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:
意外發現 TBytesStream 這個類別
但發現不能做 TBytesStream.Create(TByteDynArray)
不過卻可以寫成這樣:
TBytesStream.Create(TByte(TByteDynArray))
據說後來有改正這個缺點。
see also:
- TBytes has no type info
- Can TBytes, TByteDynArray, Array of Bytes be safely typecasted to each other?
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社群
平台和編譯器方面:
增加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 (如備份功能) 是其特色。
專用DAC,如 PgDAC, MyDAC, IbDAC 等,只支援其特定資料庫 (但 IbDAC 同時支援 Interbase 和 Firebird 兩種),支援直接連線 (Direct Connect) 和 API (如備份功能) 是其特色。
2014/10/17
Delphi 的四捨五入方法
Delphi 以往的「四捨六入五成雙」 -- Round
要改成常用的「四捨五入」,坊間有一大票使用很彆扭的方式來達成。
但 Delphi 的 Math 單元早已經有這樣的函式了:
Math.SimpleRoundTo
可是這樣的命名規則很不討喜,所以我們可以再重新封裝一下
要改成常用的「四捨五入」,坊間有一大票使用很彆扭的方式來達成。
但 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
底下是個人筆記重點:
===========================================
但這些都是 Vista (含以上) 限定, XP 以下不工作。
TTaskDialog 畫面很漂亮!學習資料:
其它新增的類別大都是為了上述元件產生的。
==================================
Code Editor 強化了許多功能和樣版(Live Templates)。大推!
消化完再走到下一版。
XE7 Add:
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:
- BDE 正式在 RAD Studio 除名,但可以從別的地方找回來。
- dbExpress 宣告死亡(Caution: dbExpress, which is described in this tutorial, is being deprecated. This means that dbExpress will be removed from RAD Studio in an upcoming release.),未來不會再提供 DBX 元件,現有的 DBX Driver 可以移轉到 FireDAC 上使用,但 FireDAC 遲早也會中止使用 DBX Driver 吧。
2014/09/10
淺談協調者模式[Mediator Pattern] - 使用 Delphi + Interface
在「深入淺出-設計模式」一書中談到「居間協調者模式」時,把它歸類在不受設計人歡迎的模式中(請參閱:14 附錄:剩下的模式-居間協調者模式)。
只是,它有提到在 MVC 中經常會使用這個模式來設計。看了下它的介紹,就真的是簡短到一個極致。
接著便拿起「參悟物件設計模式 - 使用 Delphi」一書,翻到了「協調者模式」一節。
……還是有點難理解,按本人羸弱的思考能力是這樣解讀的:
只是,它有提到在 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 的最末日
範例如下:
只是,按「易讀程式之美學」一書所建議的起始和最末範圍命名法則有點小小的衝突,
==============
Start → First
End → Last
==============
但因為不會有「32」日這種超出日期的可能,這種小缺點就忍耐一下吧 (笑)
難道 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 事件後觸發,值的變更可在此事件中處理。
單純的檢查事件,在這個事件中無法對 Sender(TField) 進行改值。
OnChange:
接在 OnValidate 事件後觸發,值的變更可在此事件中處理。
2014/02/21
DsnDBCst.dcu 找不到的問題
DsnDBCst 是 DSDesign 元件中的檔案之一。
但在 Delphi 7 之後就找不到這個檔案了,所以在編譯舊元件時可能會出錯。
而且也找不到這個神奇元件在哪邊。
所幸,萬能的 Google 大神引領我,找到了替代品
將原有的 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为何物?
但在 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为何物?
訂閱:
文章 (Atom)