Umíme to s Delphi, 36. díl – datum a čas je nade vše: měsíční kalendář

Ve 33. díle seriálu jsme si detailně popsali práci s datumem a časem v Delphi a ukázali jsme si komponentu Calendar. Ta skýtá sice relativně dost možností, nicméně – co si budeme nalhávat – její vzhled je poměrně ošklivý. Calendar ovšem naštěstí není jedinou komponentou, pomocí které si můžeme hrát s kalendářem. Popis alternativy bude náplní dnešního dílu seriálu, stejně jako další komponenta mající s kalendářem co do činění.
Kalendář „po novu“

Minulý a předminulý týden jsme přerušili popisy kalendářů, datumů a časů problematikou balíků. Dnes kalendáře dokončíme.

Ve 32. a 33. díle seriálu jsme si ukázali „klasický“, starý a především všude dostupný kalendář reprezentovaný komponentou Calendar. Dnes se podíváme na druhou komponentu s podobným účelem – na komponentu MonthCalendar, která je typu TMonthCalendar a nachází se v paletě Win32.

Podotýkám, že MonthCalendar se vyskytuje až v Delphi 5 (upřímně řečeno nevím, jak je to ve verzi Delphi 4, neboť ji momentálně nemám k dispozici; pokud o tom máte někdo přesné informace, doplňte mě prosím v diskusi). Na druhou stranu dobrou zprávou je, že ji naleznete ve všech edicích, tedy i v nejlevnější Standard. Pokud Delphi 5 nemáte, nemusíte dnešní díl seriálu zavírat, neboť v jeho závěru se začneme zabývat komponentou DateTimePicker, která je k dispozici i ve verzi Delphi 3.

Umístíte-li MonthCalendar na formulář, opět ihned (už v době návrhu) spatříte „živá data“, viz obrázek:

Klepněte pro větší obrázek

Asi je zřejmé na první pohled, že narozdíl od komponenty Calendar je vzhled měsíčního kalendáře velmi elegantní a beze studu jej můžeme použít i v aplikacích, kterými se chceme prezentovat před zákazníky.

První „zvláštnosti“ si můžete všimnout už v okamžiku, kdy se pokusíte umístit komponentu MonthCalendar na formulář. Navzdory zaběhnutému zvyku není možné zvolit libovolnou velikost komponenty, kalendář je vždy zobrazen v téže, předdefinované velikosti. Asi víte, že obvykle je možné umístit komponentu na formulář tak, že ji zvolíte v paletě, pak klepnete do určitého bodu formuláře, držíte stisknuté levé tlačítko myši a jak přesouváte kurzor myši, vidíte na formuláři obdélník, jenž určuje výslednou velikost komponenty. Když se o totéž pokusíte u MonthCalendar, uvidíte, že si nepomůžete, protože kalendář bude zobrazen stále stejně velký, jen okolo něj bude prázdný prostor (viz obrázek).

Klepněte pro větší obrázek

Když prostor pro tuto komponentu zvolíte dostatečně velký, bude kalendář mít trochu jiný vzhled – budou totiž vedle sebe zobrazeny dva měsíce (viz obrázek), případně více měsíců – jistě si dovedete představit.

Klepněte pro větší obrázek

Pojďme si nyní, stejně jako před týdnem, společně projít vlastnosti, události a metody této komponenty.

Vlastnosti komponenty MonthCalendar

Vlastnost AutoSize

Vlastnost AutoSize souvisí s tím, co jsme si uvedli o dva odstavce výše – a sice s velikostí komponenty MonthCalendar. V každém případě bude kalendář vždy stejně velký, ale pokud se prostor pro něj pokusíte myší „alokovat“ větší, jsou dvě možnosti. Buď se tento prostor, který označíte myší (nebo zadáte prostřednictvím hodnot vlastností Height a Width), vždy zmenší na velikost kalendáře (to v případě AutoSize = True) nebo zůstane okolo kalendáře volný prostor (AutoSize = False). V případě, že nastavíte AutoSize = True, zbavíte se také možnosti zobrazit najednou více měsíců, neboť velikost se vždy „smrskne“ právě na velikost jednoho měsíce.

Vlastnost BorderWidth

Možná je to už trochu nošením dříví do lesa, ale nedá mi to a musím zopakovat, že hodnotou této vlastnosti je šířka rámečku okolo kalendáře. Rámeček má ovšem standardně barvu formuláře, takže nastavením nenulové hodnoty pouze uberete kalendáři část prostoru, takže nebude zobrazen celý. Tato informace sice platí jen pro AutoSize = true, ale na druhou stranu pro AutoSize = false zase BorderWidth nemá valného smyslu :-)

Vlastnost CalColors

Ve vlastnosti CalColors můžete nastavit barvu kalendáře. Není-li vám jasné, jakou barvu, vězte, že takřka jakoukoliv. Pomocí této vlastnosti (jejíž hodnota je typu TMonthCalColors) je možné nastavit následující barvy:

  • BackColor: barva pozadí zobrazovaná vždy mezi měsíci v kalendáři. Tento atribut nemusí být implementován ve všech verzích Windows.
  • MonthBackColor: barva „hlavní části“ kalendáře, tedy pozadí za jednotlivými dny.
  • TextColor: barva, kterou se vypisují jednotlivé dny .
  • TitleBackColor: barva, kterou je tvořeno pozadí záhlaví kalendáře a také barva použitá pro zvýraznění aktuálního dne.
  • TitleTextColor: barva, kterou se v záhlaví vypisuje aktuální měsíc a také barva, kterou je vypsán aktuální den v měsíci.
  • TrailingTextColor: barva, kterou jsou vypsány dny v měsíci, který není zrovna aktuální (např. je-li aktuální září, zobrazuje se v něm i několik dnů ze srpna a z října, a to touto barvou).

Vlastnost Date

Asi jedna z nejdůležitějších vlastností kalendáře – obsahuje totiž datum, které je v kalendáři označeno. Pomocí vlastnosti Date lze toto datum přečíst nebo také nastavit. Hodnota vlastnosti Date musí ležet v rozmezí specifikovaném vlastnostmi MaxDate a MinDate. Je-li povoleno označení více dnů zároveň (MultiSelect = True), je rozpětí označených datumů udáváno vlastnostmi Date a EndDate. Typ této vlastnosti je TDate, což je typ zcela totožný s typem TDateTime (podrobný popis typu TDateTime, stejně jako ukázky toho, jak z hodnoty takového typu „dostat“ součásti datumu – den, měsíc, rok – viz předchozí díl seriálu).

Vlastnost EndDate

Zmíněná vlastnost slouží ke zjištění posledního označeného datumu v případě, že je povoleno označování více dnů zároveň (MultiSelect = True).

Vlastnost FirstDayOfWeek

Udává první den v týdnu (a tedy také den, který se zobrazuje v nejlevějším sloupci kalendáře). Může nabývat buď jedné ze sedmi hodnot přesně odpovídající anglickému názvu dne s předponou dow (např. dowMonday, dowSunday, apod.) nebo hodnoty dowLocaleDefault, která znamená, že první den v týdnu se zjistí v nastavení místních zvyklostí systému.

Vlastnost MaxDate

Umožňuje nastavit maximální (tedy nejvyšší) datum (opět typu TDate), které může uživatel v kalendáři zobrazit (posouváním po měsících).

Vlastnost MaxSelectRange

Umožňuje nastavit maximální počet dnů, které je možné zároveň vybrat (za předpokladu, že MultiSelect = True).

Vlastnost MinDate

Analogie výše popsané vlastnosti MaxDate, jen na rozdíl od MaxDate umožňuje nastavit minimální (tedy nejnižší) datum, které je možné v kalendáři zobrazit.

Vlastnost MultiSelect

Již asi stokrát zmíněná logická vlastnost říkající, je-li možné označit zároveň více dnů.

Vlastnost ShowToday

Další logická vlastnost, která udává, má-li býti pod měsíčním kalendářem uvedeno datum dnešního dne.

Vlastnost ShowTodayCircle

A do třetice logická vlastnost, podle jejíž hodnoty se dozvíme, bude-li dnešní den v kalendáři s nedbalou elegancí „zakroužkován“ červeným fixem.

Vlastnost WeekNumbers

Poslední vlastnost je opět logická; tentokráte říká, budou-li v levé části kalendáře zobrazena čísla týdnů.

Metody komponenty MonthCalendar

Tolik tedy k vlastnostem měsíčního kalendáře. Nadpis této podkapitoly není úplně přesný, spíše by se měla jmenovat „Metoda komponenty MonthCalendar“, protože si povíme jen o jediné zvláštní metodě kalendáře. Již v minulé podkapitole jsme naznačili, že to je BoldDays. Pomocí této metody je možné vyznačit několik dnů v kalendáři. Není však příliš časté pracovat s metodou BoldDays přímo. BoldDays vrací v parametru hodnotu MontBoldInfo, kterou využívá událost OnGetMonthInfo. Více informací o této události a příklad použití metody BoldDays viz příští díl seriálu.

Události komponenty MonthCalendar

Kapitola pojednávající o událostech bude také poměrně krátká, neboť se bude skládat z pouhých dvou bodů:
  • První bod není bezprostřední popis některé události, nicméně logicky k událostem patří. Všimněte si, že když v běžící aplikaci klepnete na kalendář pravým tlačítkem myši, objeví se kontextové menu s jedinou položkou: Přejít k dnešku (hovořím o českých Windows). Toto chování je zcela standardní a k tomu, aby toto kontextové menu bylo přítomno, nemusíte ani „pohnout prstem“.
  • Podobně se lze pozastavit nad klepnutím levým tlačítkem myši na údaj o měsíci a roku. V tomto případě také nemusíte „hnout prstem“ a přitom komponenta TMonthCalendar dělá divy (a málokdo by je zde čekal). :-) Při klepnutí na údaj o měsíce se otevře plovoucí okno (přesněji – kontextové menu), v němž můžete vybrat měsíc, který chcete zobrazit v kalendáři. Analogicky po klepnutí na údaj o zobrazeném roku budete mít možnost přímo zadat (případně pomocí komponenty UpDown vybrat) jiný rok. Vybraný rok se ihned v kalendáři zobrazí.
  • Nyní si popíšeme jedinou „speciální“ událost komponenty MonthCalendar. Je jí slíbená událost OnGetMonthInfo. Je vyvolána vždy, když je v kalendáři zobrazen nový měsíc. Používá se tedy s výhodou v případech, kdy chceme inicializovat zobrazení některého měsíce v kalendáři ještě dříve, než je tento měsíc skutečně zobrazen. Ideální je např. použití za účelem označit některé dny v aktuálním měsíci (jistě si dovedete představit praktické využití: budete např. programovat diář a tučně zobrazíte dny, ke kterým se pojí nějaká položka. Dalším možným využitím je zvýraznění prázdnin, státních svátků či jiných význačných dnů.). K vyznačení (tedy tučnému zobrazení) některých dnů se používá metoda BoldDays, a to zpravidla tak, jak ukazuje následující příklad.
V následující aplikaci máme na formuláři (frmHlavni) pouze komponentu MonthCalendar. Ošetříme událost OnGetMonthInfo tak, aby se v každém měsíci v přestupném roce zobrazoval tučně první, třetí a pátý den v měsíci):

unit Hlavni;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TfrmHlavni = class(TForm)
    MonthCalendar: TMonthCalendar;
    procedure MonthCalendarGetMonthInfo(Sender: TObject; Month: Cardinal;
      var MonthBoldInfo: Cardinal);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmHlavni: TfrmHlavni;

implementation

{$R *.DFM}

procedure TfrmHlavni.MonthCalendarGetMonthInfo(Sender: TObject;
  Month: Cardinal; var MonthBoldInfo: Cardinal);
begin
    MonthCalendar.BoldDays([1,3,5], MonthBoldInfo);
end;

end.

Komplexní příklad aplikace používající tuto komponentu si ukážeme v příštím dílu seriálu. Předtím však zmíníme ještě jednu komponentu, která s datumy, dny a kalendáři bezprostředně souvisí. Nachází se také v paletě Win32 a jmenuje se DateTimePicker.

Komponenta DateTimePicker

Na rozdíl od komponenty MonthCalendar se DateTimePicker nachází ve všech dostupných verzích Delphi. Při standardním nastavení je to určitá variace na téma „rozbalovací seznam ComboBox“, může ale také vypadat jako spojení komponent UpDown a Edit. V každém případě je možné údaj zadávat přímo do editačního pole. Komponenta slouží k vložení

(vybrání) datumu nebo času. Při standardním nastavení používá ve své „rozbalovací“ části námi dobře známou komponentu MonthCalendar, viz obrázek:

Klepněte pro větší obrázek

Za týden si opět uděláme krátkou procházku po vlastnostech, událostech a metodách této komponenty.

Na závěr

V dnešním díle seriálu jsme si detailně popsali komponentu MonthCalendar. Za týden budeme pokračovat slíbeným popisem komponenty DateTimePicker, za níž bude následovat příklad komplexní aplikace, která obě tyto komponenty využívá. Spojení těchto dvou komponent, jak za týden spatříte, nabízí elegantní možnost pro vývoj aplikací pracujících s datumem a časem.
Diskuze (5) Další článek: Nic nebude zadarmo, k čemu jsou mikroplatby?

Témata článku: Software, Windows, Programování, Kalendář, DEL, Přesná hodnota, Následující den, Podobný účel, Díl, První případ, Místní zvyk, První pokus, Následující měsíc, Nový měsíc, Následující rok, Čas, Prázdný prostor, Dnešní den, Datum, Místní zvyklost, Zobrazená data, Komponenta, Standardní verze, První měsíc, Pátý den


Určitě si přečtěte

PlayStation 5 bude mít extrémně rychlé SSD a promyšlenou architekturu. Sony odhalilo technické detaily

PlayStation 5 bude mít extrémně rychlé SSD a promyšlenou architekturu. Sony odhalilo technické detaily

** Sony zveřejnilo podrobnosti k PlayStationu 5 ** Poprvé jsou k dispozici technické detaily ** Sony se hodně zaměřilo na rychlost SSD

Karel Javůrek | 31

Šest nejlepších služeb a aplikací pro automatizaci online světa a chytré domácnosti

Šest nejlepších služeb a aplikací pro automatizaci online světa a chytré domácnosti

** Nastavte si automatiku na každodenní rutinní záležitosti ** Propojte online služby a chytrou domácnost ** Vybrali jsme šest nejlepších služeb pro automatizaci

Karel Kilián | 17

Vyrobíme si falešný Mac mini za tisícovku. Stačí Raspberry Pi a 3D tiskárna

Vyrobíme si falešný Mac mini za tisícovku. Stačí Raspberry Pi a 3D tiskárna

** Vyzkoušíme Raspberry Pi 4 s iRaspbianem ** Operační systém vypadá skoro jako macOS ** Vše strčíme do vlastní stylové krabice

Jakub Čížek | 29


Aktuální číslo časopisu Computer

Megatest 21 grafických karet

AMD poráží Intel už i v notebooku

Jak vytvořit 3D fotky v mobilu

Nejlepší fotoaparáty do 30 000 Kč