Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 158. – dokončení CoolBaru

Jan Šindelář 13.10.2004

Dnes si dokončíme povídání z minula a předvedeme si ještě několik drobných fint pro práci s CoolBarem. Bude to slibované přidávání komponent za běhu a práce s menu.

Začneme nejprve s menu. Minule jsme si říkali, že na CoolBar se dá umístit řada různých komponent, což značně zvyšuje jeho použitelnost vůči klasickému Toolbaru. Jisté omezení však přeci jen existuje a sice nutnost použít pouze komponenty odvozené od typu TWinControl. Jelikož menu nepatří do této skupiny, musíme toto omezení šikovně obejít.

Možná vás to překvapí, ale překonat tento problém nám pomůže právě starý ToolBar. Nejprve však umístíme na formulář nové menu a obvyklým způsobem s využitím integrovaného menu designeru navrhneme jeho strukturu a vložíme jednotlivé položky. Když se nyní podíváme v Object Inspectoru na vlastnosti formuláře, na který jsme menu umístili, uvidíme v položce Menu název našeho nově vytvořeného menu (pravděpodobně MainMenu1, pokud jste nezvolili vlastní název). To znamená, že naše menu je nyní přidruženo k příslušnému formuláři. To ovšem nechceme, protože potřebujeme menu dostat na CoolBar. Proto tuto položku smažeme a tím "odpojíme" naše menu od formuláře.

Předpokládám, že máte již z minula připravený CoolBar a pokud ne, rychle si nějaký na formulář připravte. Na CoolBar pak umístěte obyčejný starý dobrý ToolBar a na něj pak tolik tlačítek (ToolButton), kolik hlavních položek má vaše menu. Každému tlačítku pak bude odpovídat jedno rozbalovací submenu, která dohromady budou tvořit celé hlavní menu.

Asi už je vám jasné, jak celá věc funguje. Teď už stačí jen upravit vizuální stránku věci, tj. především nastavit vzhled tlačítek na Flat a zapnout (tj. nastavit na hodnotu true) zobrazování titulku pomocí parametru ShowCaptions, zapneme i položky Autosize a Grouped. Ta nejdůležitější věc nám zbývá. Spojit jednotlivá tlačítka ToolBaru s příslušnými submenu našeho hlavního menu a to prostřednictvím položky MenuItem. A to je vše, menu by již mělo fungovat. Uznávám, že jeho vytvoření je trochu složitější, ale pokud chcete mít aplikaci správně "cool", za trochu počáteční námahy to stojí.

A dostáváme se ke druhé slibované "specialitě" dnešního dne a tou je přidávání komponent na CoolBar za běhu aplikace. Je to vlastně velmi jednoduché a ukážeme si to na příkladu s komponentou DateTimePicker. Použijeme následující kratičkou proceduru:

procedure CreateDatePickerOnCoolBar;
var dtPick: TDateTimePicker;
begin
  dtPick := TDateTimePicker.Create(CoolBar1);
  dtPick.Parent := CoolBar1;
  CoolBar1.Bands.Items[Count-1].Text := `Vyberte datum`;
  dtPick.OnCloseUp := dtpOnCloseUp;
end;

Řekli jsme si, že pokud na CoolBar umístíme rovnou nějakou komponentu z palety, bude pro ni automaticky nejprve vytvořen příslušný CoolBand. Proto se přes položku Count-1 dostaneme k naposledy vytvořenému CoolBandu (na který je umístěna právě vzniknuvší komponenta) a můžeme upravit některé parametry jako je například text. Systémové zdroje, které takto nově vytvořená komponenta alokuje, nemusíme sami později uvolňovat, protože se to stane automaticky jakmile zanikne nadřazený objekt (v tomto případě CoolBar, který bude uvolněn společně s ukončením aplikace). Poslední řádek kódu, který může působit na první pohled poněkud nejasně, si hned vysvětlíme.

Takto napsaná procedura (bez posledního řádku) totiž sama o sobě nic moc neumí. Vytvoří nám komponentu, ale my bychom rádi také s komponentou pracovali, reagovali na různé události. To už samotná procedura nezvládne.

Jak ošetřit události u objektů, které jsou vytvořeny až za běhu aplikace, to by se dalo rozepsat na další článek, ale pro jednoduchost si řekneme, že pro danou událost, kterou chceme ošetřit, si nejprve nadeklarujeme v nějakém objektu (obvykle to bývá formulář, kde komponenta vzniká) příslušnou hlavičku (třeba v části public, záleží na konkrétní potřebě) a v implementační části pak kód události. A teď přichází na řadu onen zmiňovaný řádek navíc v předchozí proceduře. Ten nám přiřadí k události OnCloseUp naší komponenty DateTimePicker námi vytvořenou proceduru dtpOnCloseUp. Její kód je zde:

procedure TForm1.dtpOnCloseUp(Sender: TObject);
begin
  Memo1.Lines.Add(DateToStr((Sender as TDateTimePicker).Date));
end;

Kód je velmi jednoduchý a asi sami odhadnete, co se stane. Při uzavření DateTimePickeru (tedy při zvolení data) se vybrané datum zkopíruje do Mema.

A to je pro dnešek vše. Nyní by už pro vás neměl být problém vytvářet rozličné přepestré CoolBary. Ale jako obvykle platí, že všeho moc škodí, takže vytvářejte návrhy rozumně, přehledně, prostě s ohledem na uživatele.