TDateTimePicker je dobio svojstvo Format negde između Delphi 5 i Delphi 6. Tačna granica verzije je retko dokumentovana na način kome možete verovati, a kada naiđete na nju, prevodilac vam jednostavno kaže da identifikator ne postoji. Linija koja se kompajlira i radi na svakom novijem Delphiju koji imate, pada tiho ili potpuno na onom starom, zavisno od toga kako je projekat strukturiran
Osnovna kontrola je Windows DATETIMEPICK_CLASS zajednička kontrola iz comctl32.dll, i uvek je prihvatala string formata kroz poruku DTM_SETFORMAT. Delphi-jev VCL omotava (wraps) tu poruku u svojstvo Format na novijim verzijama. Na Delphi 5, poruku šaljete sami preko makro omotača DateTime_SetFormat deklarisanog u CommCtrl-u
Obrazac uslovnog kompajliranja
Standardni pristup je blok uslovnog kompajliranja zasnovan na simbolu verzije. Delphi 5 definiše VER130; možete testirati direktno na njega ili definisati sopstveni simbol D5 u opcijama projekta kako bi oznaka grane bila čitljivija u celoj bazi koda. U svakom slučaju, grana Delphi 5 poziva DateTime_SetFormat sa kontrolnim handle-om; svaka druga grana dodeljuje svojstvo:
{$IFDEF D5}
DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}
Dodajte CommCtrl u sekciju uses za jedinicu (unit) koja sadrži granu Delphi 5. Nema potrebe da ga dodajete bezuslovno; ako više volite da zavisnost bude ograničenog obima, obmotajte unos uses u isti uslov:
uses
...,
{$IFDEF D5}
CommCtrl,
{$ENDIF}
...;
Sintaksa stringa formata
String formata koji se prosleđuje DateTime_SetFormat prati format Windows alata za izbor datuma i vremena (date-time picker), a ne Delphi-jeve FormatDateTime tokene. Izgledaju slično, ali nisu zamenjivi. Windows koristi d za dan u mesecu (bez vodeće nule), dd za dan sa vodećom nulom, M za broj meseca, MM za mesec sa vodećom nulom, yy za dvocifrenu godinu i yyyy za četvorocifrenu godinu. Vremenska polja koriste h/hh za časove u 12-časovnom formatu, H/HH za 24-časovni, m/mm za minute, s/ss za sekunde. Doslovni tekst (literal) ide unutar jednostrukih navodnika unutar stringa formata, tako da je 'dd/MM/yyyy' već ispravno, ali 'dd '<literal>' MM' bi zahtevalo ugniježđene parove jednostrukih navodnika
Nasuprot tome, Delphi-jev FormatDateTime koristi d/dd/ddd/dddd za forme dana sa drugačijom semantikom, i m za mesec (a ne M). Ako kopirate string formata iz poziva FormatDateTime i direktno ga prosledite na DateTime_SetFormat, polja za mesec i minut će verovatno biti zamenjena u izlazu. Napišite string formata kontrole od nule u skladu sa Windows dokumentacijom, umesto da konvertujete iz Delphi formata
Regionalna podešavanja i globalni ShortDateFormat
Promena Delphi-jeve globalne promenljive ShortDateFormat ne utiče na TDateTimePicker koji je već kreiran. Alat za izbor (picker) čita regionalna podešavanja iz operativnog sistema Windows u vreme kreiranja i nakon toga vrši renderovanje prema porukama koje prima, a ne prema Delphi RTL globalnim promenljivama. To znači da postavljanje ShortDateFormat u FormCreate neće promeniti ono što kontrola prikazuje. Potreban vam je DateTime_SetFormat (ili svojstvo Format na novijem Delphiju) da biste zamenili (override) sopstveni string formata kontrole nakon što handle postoji
Za aplikacije koje se primenjuju na međunarodnom nivou, testirajte string formata na mašini sa regionalnim podešavanjima koja nisu za SAD. Windows može da zameni prazan ili nil string formata sa podrazumevanim lokalnim, ali eksplicitni ne-nil string u potpunosti poništava regionalno podešavanje. To je obično ono što želite, ali to znači da će se obrazac usmeren na SAD, kao što je 'MM/dd/yyyy', pojaviti onakav kakav jeste korisnicima koji po konvenciji očekuju dd/MM/yyyy. Ako je alat za izbor datuma okrenut prema korisniku umesto da bude čisto polje za unos podataka, razmislite o tome da prepustite kontroli podrazumevano ponašanje (prosledite nil funkciji DateTime_SetFormat) kako bi automatski pratila lokalna podešavanja korisnika
Ponovno kreiranje handle-a
Podešavanje formata pripada handle-u prozora, a ne bilo kom polju VCL objekta. Ako je handle kontrole uništen i ponovo kreiran, što VCL može da uradi kada promenite roditelja kontrole (reparent) ili promenite određena svojstva stila tokom izvršavanja, format se vraća na podrazumevani Windows format. Sigurno mesto za primenu DateTime_SetFormat je u hendleru koji se pokreće nakon kreiranja handle-a: zamenite (override) CreateWnd u klasi potomku i pozovite ga tamo, ili ga primenite u događajima OnEnter ili OnShow tek nakon što potvrdite da je handle živ. Njegovo postavljanje jednom u FormCreate je često dovoljno za jednostavne forme, ali nije pouzdano ako forma vrši dinamičko prebacivanje stila ili promenu roditelja kontrole
Isto ograničenje važi i za svojstvo Format VCL-a na novijim verzijama Delphija; interno ono poziva istu Windows poruku i suočava se sa istim životnim ciklusom handle-a. Razlika je u tome što postavljač (setter) VCL svojstva proverava da li je handle dodeljen pre nego što ga prosledi i automatski ponovo primenjuje format na CreateWnd. Sirov poziv DateTime_SetFormat nema takvu zaštitu, tako da grana Delphi 5 mora biti promišljenija o tome kada se pokreće
Uklanjanje zaobilaznog rešenja
Kada projekat ukine podršku za Delphi 5, uslovni blok postaje mrtav teret. Uklonite {$IFDEF D5} granu i importovanje CommCtrl-a sa ograničenim obimom, ostavljajući samo direktnu dodelu svojstva Format. Ostavite uklanjanje u jednom commit-u (urezivanju) kako biste lako identifikovali ako se nešto neočekivano pokvari na prevodiocu (compiler) koji niste testirali. Sam string formata ostaje isti; samo se mehanizam isporuke menja