A TDateTimePicker valamikor a Delphi 5 és a Delphi 6 között kapott egy Format tulajdonságot. A pontos verzióhatár ritkán van úgy dokumentálva, hogy bízni lehessen benne, és amikor beleütközik, a fordító egyszerűen közli, hogy az azonosító nem létezik. Az a sor, amely minden újabb Delphin fordul és működik, csendben vagy egyenesen elbukik a régin, attól függően, hogy a projekt hogyan van strukturálva
A mögöttes vezérlő a Windows DATETIMEPICK_CLASS közös vezérlője (common control) a comctl32.dll fájlból, és mindig is elfogadott egy formátumkarakterláncot a DTM_SETFORMAT üzeneten keresztül. A Delphi VCL ezt az üzenetet a Format tulajdonságba csomagolja az újabb verziókon. Delphi 5-ben ezt az üzenetet saját maga küldi el a CommCtrl-ben deklarált DateTime_SetFormat makró burkolón keresztül
A feltételes fordítási minta
A szabványos megközelítés egy verziószimbólumhoz kötött feltételes fordítási blokk. A Delphi 5 a VER130-at definiálja; közvetlenül tesztelhet ellene, vagy meghatározhatja saját D5 szimbólumát a projekt beállításaiban, hogy az elágazás címkéje olvashatóbb legyen a kódbázisban. Akárhogy is, a Delphi 5 elágazás a DateTime_SetFormat függvényt hívja meg a vezérlő leírójával; minden más elágazás a tulajdonságot rendeli hozzá:
{$IFDEF D5}
DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}
Adja hozzá a CommCtrl-t a uses záradékhoz ahhoz a unit-hoz, amely a Delphi 5 elágazást tartalmazza. Nincs szükség feltétel nélküli hozzáadására; ha inkább hatókörön belül (scoped) szeretné tartani a függőséget, csomagolja be a uses bejegyzést ugyanabba a feltételbe:
uses
...,
{$IFDEF D5}
CommCtrl,
{$ENDIF}
...;
Formátumkarakterlánc szintaxis
A DateTime_SetFormat-nak átadott formátumkarakterlánc a Windows dátum- és időválasztó formátumát követi, nem pedig a Delphi FormatDateTime tokenjeit. A kettő hasonlónak tűnik, de nem felcserélhetők. A Windows a d-t használja a hónap napjához (vezető nulla nélkül), a dd-t a nullával kiegészített naphoz, az M-et a hónap számához, az MM-et a nullával kiegészített hónaphoz, a yy-t a kétjegyű évhez, és az yyyy-t a négyjegyű évhez. Az időmezők a h/hh formátumot használják a 12 órás órákhoz, a H/HH-t a 24 óráshoz, a m/mm-t a percekhez, az s/ss-t a másodpercekhez. A literális szöveg a formátumkarakterláncon belül szimpla idézőjelek közé kerül, így a 'dd/MM/yyyy' már helyes, de a 'dd '<literal>' MM' beágyazott szimpla idézőjelpárokat igényelne
Ezzel szemben a Delphi FormatDateTime a d/dd/ddd/dddd formátumokat használja különböző szemantikájú napformátumokhoz, és a m-et a hónaphoz (nem M-et). Ha lemásol egy formátumkarakterláncot egy FormatDateTime hívásból, és közvetlenül átadja a DateTime_SetFormat-nak, a hónap és a perc mezők valószínűleg fel lesznek cserélve a kimenetben. Írja meg a vezérlő formátumkarakterláncát a semmiből a Windows dokumentációja alapján, ahelyett, hogy Delphi formátumból konvertálná
Területi beállítások és a globális ShortDateFormat
A Delphi globális ShortDateFormat változójának módosítása nem befolyásolja a már létrehozott TDateTimePicker vezérlőt. A választó a létrehozásakor beolvassa a területi beállításokat a Windowsból, és ezt követően a kapott üzenetek alapján végez renderelést, nem pedig a Delphi RTL globális változói alapján. Ez azt jelenti, hogy a ShortDateFormat beállítása a FormCreate-ben nem változtatja meg azt, amit a vezérlő megjelenít. Szüksége van a DateTime_SetFormat (vagy újabb Delphi verziókon a Format tulajdonság) használatára ahhoz, hogy felülírja a vezérlő saját formátumkarakterláncát a leíró (handle) létezése után
A nemzetközileg telepített alkalmazások esetében tesztelje a formátumkarakterláncot egy olyan gépen, amely nem amerikai területi beállításokkal rendelkezik. A Windows felülbírálhat egy üres vagy nil formátumkarakterláncot a területi alapértelmezéssel, de egy explicit, nem nil karakterlánc teljes mértékben felülírja a területi beállítást. Általában ezt szeretné, de ez azt jelenti, hogy egy amerikai központú minta, mint például a 'MM/dd/yyyy', pontosan így fog megjelenni azoknak a felhasználóknak, akik a konvenció szerint a dd/MM/yyyy formátumot várják. Ha a dátumválasztó (date picker) a felhasználó felé néz (user-facing), és nem csupán tiszta adatbeviteli mező, fontolja meg, hogy hagyja a vezérlőt alapértelmezésen (adjon át nil-t a DateTime_SetFormat-nak), így automatikusan követi a felhasználó területi beállításait
Leíró (handle) újralétrehozása
A formátumbeállítás az ablak leírójához (window handle) tartozik, nem pedig egy VCL objektum mezőhöz. Ha a vezérlő leírója megsemmisül és újra létrejön – amit a VCL akkor tehet, ha átnevel egy vezérlőt (reparent), vagy bizonyos stílustulajdonságokat módosít futásidőben –, a formátum visszaáll a Windows alapértelmezésére. A biztonságos hely a DateTime_SetFormat alkalmazására egy olyan kezelő, amely a leíró létrehozása után fut: bírálja felül (override) a CreateWnd metódust egy leszármazott osztályban, és hívja meg ott, vagy alkalmazza az OnEnter vagy OnShow eseményben, miután megbizonyosodott arról, hogy a leíró él. A FormCreate-ben történő egyszeri beállítás gyakran elegendő az egyszerű űrlapokhoz, de nem megbízható, ha az űrlap dinamikus stílusváltást vagy vezérlőátnevelést végez
Ugyanez a korlátozás vonatkozik az újabb Delphi verziókon lévő VCL Format tulajdonságra is; belsőleg ugyanazt a Windows üzenetet hívja, és ugyanazzal a leíró-életciklussal (handle lifecycle) néz szembe. A különbség az, hogy a VCL tulajdonságbeállító ellenőrzi, hogy a leíró le van-e foglalva az áthívás előtt, és a CreateWnd hívásakor automatikusan újra alkalmazza a formátumot. A nyers DateTime_SetFormat hívás nem rendelkezik ilyen védelemmel, ezért a Delphi 5 elágazásnak sokkal tudatosabbnak kell lennie azzal kapcsolatban, hogy mikor fut
Az áthidaló megoldás eltávolítása
Amikor egy projekt eldobja a Delphi 5 támogatást, a feltételes blokk holtsúllyá válik. Távolítsa el az {$IFDEF D5} elágazást és a hatókörhöz kötött CommCtrl importálást, csak a közvetlen Format tulajdonság-hozzárendelést hagyva meg. Tartsa az eltávolítást egyetlen commitban, így könnyű azonosítani, ha valami váratlanul elromlik egy olyan fordítón, amelyet nem tesztelt. Maga a formátumkarakterlánc ugyanaz marad; csak a kézbesítési mechanizmus változik