Techninis straipsnis

TDateTimePicker formatas „Delphi 5“: „DateTime_SetFormat“

TDateTimePicker įgijo Format ypatybę kažkur tarp „Delphi 5“ ir „Delphi 6“. Tiksli versijos riba retai dokumentuojama patikimu būdu, ir kai su ja susiduriate, kompiliatorius tiesiog praneša, kad identifikatorius neegzistuoja. Eilutė, kuri kompiliuojama ir veikia su kiekviena naujesne „Delphi“ versija, senojoje nepavyksta tyliai arba visiškai, priklausomai nuo to, kaip sukurta projekto struktūra

Pagrindinis valdiklis yra „Windows“ DATETIMEPICK_CLASS bendrasis valdiklis iš comctl32.dll, ir jis visada priimdavo formato eilutę per DTM_SETFORMAT pranešimą. „Delphi“ VCL naujesnėse versijose apgaubia tą pranešimą Format ypatybe. Naudojant „Delphi 5“, pranešimą siunčiate patys per DateTime_SetFormat makrokomandos apvalkalą, deklaruotą CommCtrl

Sąlyginio kompiliavimo modelis

Standartinis metodas yra kompiliatoriaus sąlyginis blokas, susietas su versijos simboliu. „Delphi 5“ apibrėžia VER130; galite tikrinti jį tiesiogiai arba projekto parinktyse apibrėžti savo D5 simbolį, kad šakos etiketė būtų skaitomesnė visoje kodo bazėje. Bet kuriuo atveju, „Delphi 5“ šaka iškviečia DateTime_SetFormat su valdiklio rodykle; kiekviena kita šaka priskiria ypatybę:

{$IFDEF D5}
  DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
  DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}

Pridėkite CommCtrl prie uses sąlygos blokui, kuriame yra „Delphi 5“ šaka. Nėra jokio poreikio pridėti jo besąlygiškai; jei norite, kad priklausomybė būtų apribota, apgaubkite uses įrašą ta pačia sąlyga:

uses
  ...,
{$IFDEF D5}
  CommCtrl,
{$ENDIF}
  ...;

Formato eilutės sintaksė

Formato eilutė, perduodama į DateTime_SetFormat, atitinka „Windows“ datos ir laiko pasirinkimo formatą, o ne „Delphi“ FormatDateTime žymėtojus. Jie atrodo panašiai, bet nėra sukeičiami. „Windows“ naudoja d mėnesio dienai (be nulių priekyje), dd dienai su nuliu priekyje, M mėnesio numeriui, MM mėnesiui su nuliu priekyje, yy dviženkliams metams ir yyyy keturženkliams metams. Laiko laukai naudoja h/hh 12 valandų formatui, H/HH 24 valandų, m/mm minutėms, s/ss sekundėms. Tiesioginis tekstas formatavimo eilutėje rašomas viengubose kabutėse, todėl 'dd/MM/yyyy' jau yra teisingas, bet 'dd '<literal>' MM' reikalautų įterptų viengubų kabučių porų

Priešingai, „Delphi“ FormatDateTime naudoja d/dd/ddd/dddd dienų formoms su skirtinga semantika, ir m mėnesiui (ne M). Jei nukopijuosite formato eilutę iš FormatDateTime iškvietimo ir tiesiogiai perduosite ją DateTime_SetFormat, rezultate mėnesio ir minučių laukai tikriausiai bus sukeisti. Geriau rašykite valdiklio formato eilutę nuo nulio pagal „Windows“ dokumentaciją, o ne konvertuokite iš „Delphi“ formato

Regioniniai nustatymai ir pasaulinis ShortDateFormat

„Delphi“ pasaulinio kintamojo ShortDateFormat pakeitimas neturi įtakos jau sukurtam TDateTimePicker. Pasirinkiklis nuskaito regioninius nustatymus iš „Windows“ kūrimo metu ir vėliau vaizduojamas pagal gaunamus pranešimus, o ne pagal „Delphi“ RTL pasaulinius kintamuosius. Tai reiškia, kad ShortDateFormat nustatymas FormCreate nepakeis to, ką rodo valdiklis. Jums reikia DateTime_SetFormat (arba Format ypatybės naujesnėse „Delphi“ versijose), kad nepaisytumėte paties valdiklio formato eilutės, kai rodyklė jau egzistuoja

Tarptautiniu mastu platinamoms programoms išbandykite formato eilutę kompiuteryje su ne JAV regioniniais nustatymais. „Windows“ gali pakeisti tuščią ar nulinę formato eilutę pagal vietovės numatytuosius nustatymus, tačiau aiškiai nurodyta ne nulinė eilutė visiškai pakeičia regioninius nustatymus. Paprastai to ir norite, tačiau tai reiškia, kad į JAV orientuotas modelis, pvz., 'MM/dd/yyyy', vartotojams, kurie pagal susitarimą tikisi dd/MM/yyyy, atrodys taip, kaip parašyta. Jei datos pasirinkiklis yra skirtas vartotojui, o ne grynas duomenų įvedimo laukas, apsvarstykite galimybę leisti valdikliui naudoti numatytuosius nustatymus (perduoti nil į DateTime_SetFormat), kad jis automatiškai prisitaikytų prie vartotojo lokalės

Rodyklės atkūrimas

Formato nustatymas priklauso lango rodyklei, o ne jokiam VCL objekto laukui. Jei valdiklio rodyklė sunaikinama ir sukuriama iš naujo (tai VCL gali padaryti keičiant valdiklio pirminį elementą arba vykdymo metu keičiant tam tikras stiliaus ypatybes), formatas grįžta į „Windows“ numatytąjį. Saugi vieta pritaikyti DateTime_SetFormat yra apdorojimo priemonė, kuri paleidžiama sukūrus rodyklę: perrašykite CreateWnd palikuonio klasėje ir iškvieskite jį ten, arba pritaikykite OnEnter ar OnShow įvykyje tik patvirtinę, kad rodyklė yra aktyvi. FormCreate vienkartinis nustatymas dažnai pakankamas paprastoms formoms, tačiau tai nėra patikima, jei forma dinamiškai perjungia stilius arba keičia valdiklių pirminius elementus

Tas pats apribojimas taikomas VCL Format ypatybei naujesnėse „Delphi“ versijose; viduje ji iškviečia tą patį „Windows“ pranešimą ir susiduria su tuo pačiu rodyklės gyvavimo ciklu. Skirtumas tas, kad VCL ypatybės nustatymo priemonė patikrina, ar rodyklė priskirta prieš iškviečiant, ir automatiškai pritaiko formatą iš naujo CreateWnd metu. Tiesioginis DateTime_SetFormat iškvietimas neturi tokios apsaugos, todėl „Delphi 5“ šaka turi būti kruopštesnė dėl to, kada ji paleidžiama

Problemos sprendimo būdo pašalinimas

Kai projektas nustoja palaikyti „Delphi 5“, sąlyginis blokas tampa nebereikalingas. Pašalinkite {$IFDEF D5} šaką ir apribotą CommCtrl importavimą, palikdami tik tiesioginį Format ypatybės priskyrimą. Išlaikykite šį pašalinimą viename pateikime, kad būtų lengva nustatyti, jei kažkas netikėtai sugestų kompiliatoriuje, kurio neišbandėte. Pati formato eilutė išlieka ta pati; keičiasi tik perdavimo mechanizmas