在給一箇舊 VCL 示例增加 Delphi 5 相容性時,專案在一行對新版 Delphi 來說完全正常的程式碼上失敗了。該程式碼試圖直接給 TDateTimePicker.Format 屬性賦自定義日期格式。
|
1 |
DateTimePicker.Format := 'MM/dd/yyyy'; |
TDateTimePicker 是 Windows common control 的 VCL 封裝。新版 Delphi 提供了方便的 Format 屬性,但 Delphi 5 沒有。在 Delphi 5 及更早版本中,控制元件通常會跟隨 Windows 區域日期設定,除非直接向底層 common control 傳送訊息。
Delphi 5 使用 common-control API
相容性修復是在 Delphi 5 分支中呼叫 CommCtrl 單元裡的 DateTime_SetFormat,同時讓新版編譯器繼續使用直接屬性賦值。編譯 Delphi 5 分支時,需要把 CommCtrl 加入 uses。
|
1 2 3 4 5 |
{$IFDEF D5} DateTime_SetFormat(DateTimePicker.Handle, PChar('MM/dd/yyyy')); {$ELSE} DateTimePicker.Format := 'MM/dd/yyyy'; {$ENDIF} |
為什麼 ShortDateFormat 不夠
修改 Delphi 的全域性日期格式變數,並不能可靠改變由 Windows common control 支撐的日期時間選擇器。控制元件按照自身設定和收到的訊息渲染,這就是 Delphi 5 中應使用 DateTime_SetFormat 的原因。
這種區別對跨版本示例尤其重要。Delphi 7 或 Delphi 2009 中乾淨的一行程式碼,在 Delphi 5 中可能根本不存在;而 Windows common-control 訊息仍可使用。條件編譯能讓每個編譯器走最自然的路徑。
測試舊版本相容性
應用修復後,同時測試顯示值和儲存值。格式隻影響使用者看到的內容,不應改變計算使用的底層 TDateTime 值。在訂單、發票和電子表格匯出中,顯示格式與數值日期保持一致非常重要。
如果控制元件控制代碼被重建,也要重新檢查格式。某些 VCL 控制元件在銷燬並重新建立視窗控制代碼後會丟失原生控制元件狀態。若應用執行時改變樣式或父控制元件,請在控制代碼可用後再應用格式。
當專案不再需要 Delphi 5 支援時,可以刪除條件分支,只保留直接的 Format 屬性賦值。在此之前,把相容程式碼放在控制元件初始化附近,說明它是 VCL 控制元件限制的 workaround,而不是業務計算邏輯的一部分。