TDateTimePicker fikk en Format-egenskap et sted mellom Delphi 5 og Delphi 6. Den nøyaktige versjonsgrensen er sjelden dokumentert på en måte du kan stole på, og når du treffer den, forteller kompilatoren deg ganske enkelt at identifikatoren ikke eksisterer. Linjen som kompilerer og fungerer på alle nyere Delphi-versjoner du har, feiler i stillhet eller direkte på den gamle, avhengig av hvordan prosjektet er strukturert
Den underliggende kontrollen er Windows DATETIMEPICK_CLASS felleskontroll fra comctl32.dll, og den har alltid godtatt en formatstreng via meldingen DTM_SETFORMAT. Delphis VCL pakker inn den meldingen i egenskapen Format på nyere versjoner. På Delphi 5 sender du meldingen selv via makro-innpakningen DateTime_SetFormat deklarert i CommCtrl
Mønsteret for betinget kompilering
Standardtilnærmingen er en kompilatorbetinget blokk basert på et versjonssymbol. Delphi 5 definerer VER130; du kan teste mot dette direkte eller definere ditt eget D5-symbol i prosjektalternativene for å gjøre forgreningens etikett mer lesbar på tvers av kodebasen. Uansett kaller Delphi 5-grenen DateTime_SetFormat med kontrollhåndtaket; alle andre grener tilordner egenskapen:
{$IFDEF D5}
DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}
Legg til CommCtrl i uses-klausulen for enheten som inneholder Delphi 5-grenen. Det er ikke nødvendig å legge den til ubetinget; hvis du foretrekker å holde avhengigheten begrenset, kan du pakke inn uses-oppføringen i den samme betingelsen:
uses
...,
{$IFDEF D5}
CommCtrl,
{$ENDIF}
...;
Syntaks for formatstreng
Formatstrengen som sendes til DateTime_SetFormat, følger Windows-formatet for dato-tid-velgeren, ikke Delphis FormatDateTime-tokens. De to ser like ut, men kan ikke brukes om hverandre. Windows bruker d for dag i måneden (ingen ledende null), dd for null-fylt dag, M for månedsnummer, MM for null-fylt måned, yy for tosifret år og yyyy for firesifret år. Tidsfelt bruker h/hh for 12-timers timer, H/HH for 24-timers timer, m/mm for minutter, s/ss for sekunder. Bokstavelig tekst settes i enkle anførselstegn inne i formatstrengen, så 'dd/MM/yyyy' er allerede korrekt, men 'dd '<literal>' MM' vil kreve innebygde par med enkle anførselstegn
Delphis FormatDateTime bruker derimot d/dd/ddd/dddd for dagsformer med en annen semantikk, og m for måned (ikke M). Hvis du kopierer en formatstreng fra et FormatDateTime-kall og sender den direkte til DateTime_SetFormat, vil måneds- og minuttfelt sannsynligvis bli byttet om i utdataene. Skriv kontrollens formatstreng fra bunnen av basert på Windows-dokumentasjonen i stedet for å konvertere fra et Delphi-format
Regionale innstillinger og den globale ShortDateFormat
Å endre Delphis globale variabel ShortDateFormat påvirker ikke en TDateTimePicker som allerede er opprettet. Velgeren leser regionale innstillinger fra Windows ved opprettelsestidspunktet og gjengir deretter i henhold til meldingene den mottar, ikke de globale Delphi RTL-variablene. Det betyr at å angi ShortDateFormat i FormCreate ikke vil endre det kontrollen viser. Du trenger DateTime_SetFormat (eller egenskapen Format på nyere Delphi) for å overstyre kontrollens egen formatstreng etter at håndtaket (handle) eksisterer
For applikasjoner som rulles ut internasjonalt, test formatstrengen på en maskin med en ikke-amerikansk regional innstilling. Windows kan overstyre en blank eller nil formatstreng med lokal standard, men en eksplisitt ikke-nil streng overstyrer den regionale innstillingen fullstendig. Det er vanligvis det du ønsker, men det betyr at et USA-sentrert mønster som 'MM/dd/yyyy' vil vises som det er for brukere som forventer dd/MM/yyyy i henhold til konvensjonen. Hvis datovelgeren er brukerrettet i stedet for et rent dataregistreringsfelt, bør du vurdere å la kontrollen bruke standard (send nil til DateTime_SetFormat) slik at den automatisk følger brukerens locale
Gjenoppretting av håndtak (handle)
Formatinnstillingen tilhører vindushåndtaket, ikke noe VCL-objektfelt. Hvis kontrollens håndtak ødelegges og gjenopprettes, noe VCL kan gjøre når du endrer forelder for en kontroll eller endrer visse stilegenskaper ved kjøretid, går formatet tilbake til Windows-standarden. Det trygge stedet å bruke DateTime_SetFormat er i en behandler som kjører etter oppretting av håndtak: overstyr CreateWnd i en etterkommerklasse og kall det der, eller bruk det i hendelsen OnEnter eller OnShow, men kun etter å ha bekreftet at håndtaket er aktivt. Å sette det én gang i FormCreate er ofte tilstrekkelig for enkle skjemaer, men det er ikke pålitelig hvis skjemaet utfører dynamisk stilbytte eller endring av kontrollens forelder
Den samme begrensningen gjelder for VCL Format-egenskapen på nyere Delphi-versjoner; internt kaller den samme Windows-melding og møter den samme livssyklusen for håndtaket. Forskjellen er at VCL-egenskapens setter sjekker om håndtaket er tildelt før anropet sendes gjennom, og den påfører formatet automatisk på nytt ved CreateWnd. Det rå anropet DateTime_SetFormat har ingen slik beskyttelse, så Delphi 5-grenen må være mer bevisst på når det kjøres
Fjerning av omgåelsen
Når et prosjekt slutter å støtte Delphi 5, blir den betingede blokken dødvekt. Fjern {$IFDEF D5}-grenen og den begrensede CommCtrl-importen, og la kun den direkte tilordningen av Format-egenskapen stå igjen. Hold fjerningen i én enkelt commit, slik at det er lett å identifisere hvis noe uventet går i stykker på en kompilator du ikke testet. Selve formatstrengen forblir den samme; det er kun leveringsmekanismen som endres