Speciální menu - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Speciální menu

delphi_extramenu

18. května 2001, 00.00 | Chcete ve své aplikaci ve Windows vytvořit zajímavé menu s obrázkem a mnoha možnostmi? Ukážeme vám jak na to!



Znáte menu z Windows XX ? Jakby ne, vždyť jej vidíte určitě několikrát za den. Proč se ptám ? Určitě jste si všimli, že vlevo od menu je obrázek, a ikony v menu jsou větší. A právě něco takového si dnes zkusíme udělat.

Komponenta MainMenu ani PopupMenu však žádnou vlastnost LeftImage a ItemHeight nemají. Máme sice ještě jednu možnost - stáhnout si nějakou komponentu z internetu. Ovšem, to bych nemusel psát dnešní článek, a vy byste se nedpzvěděli, jakže na takové hezké menu.
Nebudu vás dlouho napínat, a prozradím vám, že komponenta MainMenu má vlastnost OwnerDraw, která určuje, jestli si budeme položky kreslit sami, nebo jestli to necháme na windows. dáme si tedy jednu komponentu na formulář a nastavíme vlastnost OwnerDraw na true. Samozřejmě ještě musíme přidat nějaké ty položky, ale to nechám již na vás. Projekt si uložte a zkuste jej spustit. Výsledek by měl vypadat nějak takto:


Položky jsou tak trochu malé. To je proto, že windows nechali na nás, ať si určíme, jak je chceme velké, a jelikož jsme si ještě nic neurčili, jsou takto malé. Tímto tedy začneme. Vybereme nějakou položku, a vytvoříme k ní proceduru OnMeasureItem. Do ní vložíme následující kód, který nastaví velikost na 30x200 pixelů:


procedure TForm1.Item1MeasureItem(Sender: TObject; 
ACanvas: TCanvas; var Width, Height: Integer);
begin
 // nastavení velikosti...
 width:=200;
 Height:=30;
end;


Nyní tuto proceduru přiřadíme všem položkám, a můžeme projekt znovu spustit. Jak bude vypadat ukazuje následující obrázek:


Velikost tedy máme, přistoupíme k vlastnímu kreslení. To zajistí procedura OnDrawItem, kterou opět vytvoříme, a následně přiřadíme ke všem položkám.
Nejprve musíme zjistit, kterou tu položku vlastně kreslíme, a podle toho přizpůbosit text, obrázek, klávesovou zkratku atd. Definujeme si tedy pár proměnných:


var text,               // text na položce
    napoveda:string;    // nápověda položky
    zkratka:TShortCut;  // klávesová zkratka
    Image:integer;      // číslo obrázku


A hned si je nastavíme:


with Sender as TMenuItem do  // zjistíme info o položce
  begin                       // kterou jdeme kreslit
   Text:=caption;
   Zkratka:=ShortCut;
   Image:=ImageIndex;
   Napoveda:=Hint;
  end;


Nyní již víme i vlastnosti, zbývá nám jen položku nakreslit. Kreslit budeme na povrch ACanvas, a velikost povrchu je uložena v ARect. Jelikož však je mezi jednotlivými items mezera, nejprve si ARect funkci InflateRect zvětšíme, vyplníme šedou barvou a zase zmenšíme. Potom posuneme levý okraj ARectu o 30 pixelů doprava, abychom udělali místo pro náš modrý pruh. Následovat bude kreslení pozadí, buď oranžového pokud je položka vybraná, nebo šedého, pokud ne. Jestli je vybraná poznáme podle proměnné Selected. Zde je první část procedury, která toto celé zajistí:


with ACanvas do
  begin
   InflateRect(Arect,1,1); // zvětšíme rect o 1 na každé straně
   Pen.Style:=psSolid;     // vymažeme to
   Pen.Width:=1;
   Pen.Color:=$00DCE4E7;
   ACanvas.Brush.Color:=$00DCE4E7;
   Rectangle(ARect);
   InflateRect(ARect,-1,-1); // a zase ho zvětšíme nazpátek
   ARect.Left:=30;           // uděláme místo pro levý pruh...

   // nejprve nakreslíme pozadí, 
   // abychom poznali jestli je vybraná ...
   if Selected then
    begin
     Pen.Style:=psSolid;
     Pen.Width:=1;
     Pen.Color:=$0047B1F8;
     ACanvas.Brush.Color:=$0044D7FB;
     Rectangle(ARect);
    end
   else
    begin
     Pen.Style:=psSolid;
     Pen.Width:=1;
     Pen.Color:=$00DCE4E7;
     ACanvas.Brush.Color:=$00DCE4E7;
     Rectangle(ARect);
    end;
  end;


Projekt můžeme znovu spustit. Je hned hezčí:


Ovšem text se nám nějak ztratil, proto si jej nyní nakreslíme. Nejprve si nastavíme Font.Name na 'Tahoma', nebo jiný font. Pokud však nyní zkusíme použít TextOut, zjistíme, že se nám napíše text např. &Item, nebo O&tevřít. To necheme, a proto tímto řádkem odfiltrujeme z proměnné Text znak &:


  Delete(text,Pos('&',text),1); // odstranit & z textu


Já jsem si však vymyslel ještě jednu specialitku, a to zcela originální zobrazování hintu (nápovědy). Pokud není položka vybraná, je vidět pouze text Text, ale pokud nad ní najedete myší, Text se posune o trochu nahoru a pod ním se objeví text z proměnné Napoveda. Jak to vypadá se můžete podívat na obrázku úplně nahoře. Další problém je klávesová zkratka, kterou máme uloženou v proměnné Zkratka. Aby byla zobrazená zarovnaná doprava, musíme nejprve zjistit šířku textu Zkratka (přes TextWidth()) a poté toto číslo odečíst od šířky položky (200). Tím získáme x-ovou pozici textu a můžeme jej vypsat. Předtím však musíme převést zkratuk na string, funkcí ShortCutToText(). Zde je výpis zobrazení textu a klávesové zkratky:


   ...

   Font.Name:='Tahoma';

   Delete(text,Pos('&',text),1); // odstranit & z textu

   // podle toho, jestli je položka vybraná
   // nakreslíme buď jen samotnou, nebo i s hintem
   if selected then
    begin
     Font.Size:=8;
     Font.Style:=[fsBold];
     Font.Color:=clRed;
     TextOut(ARect.Left+28,ARect.Top+2,text);
     Font.Size:=7;
     Font.Style:=[];
     TextOut(ARect.Left+35,ARect.Top+16,napoveda);
    end
   else if selected = false then
    begin
     Font.Color:=clMenuText;
     Font.Size:=8;
     Font.Style:=[fsBold];
     TextOut(ARect.Left+28,ARect.Top+8,text);
    end;

   // SHORTCUT  - klávesová zkratka
   FOnt.Size:=8;
   Font.Style:=[];
   TextOut(200-TextWidth(ShortCutToText(zkratka)),
   ARect.Top+8,ShortCutToText(zkratka));

   ...


Po těchto úpravách bude náš projekt vypadat nějak takto (pokud nevidíte klávesovou zkratku, nebo nápovědu, je to tím, že jste si u položky nanastavili vlastnost Shortcut a Hint):


Nyní přijde na řadu náš slibovaný levý pruh, který můžete samozřejmě jednoduše nahradit za obrázek. Jeho nakreslení je opravdu jednoduché, proto snad nepotřebuje dalších komentářů:


   // proužek vlevo
   Brush.Color:=$00E8E0DB;
   Pen.Color:=$00B89E8F;
   Pen.Style:=psSolid;
   Pen.Width:=1;
   Rectangle(1,1,28,4*30-2);


Chybí nám ještě obrázky. Dáme si na formulář komponentu ImageList, které nastavíme vlastnost width a height na rozměry našich obrázků (v mém případě 24x24). Jak vydíte, nejsme zde nijak omezeni :) Dále nastavíme u jednotlivých položek vlastnost ImageIndex na index chtěného obrázku a zbývá jen následující kód:


   // nakreslení obrázku...
   ImageList1.Draw(ACanvas,32,ARect.Top + 2,Image);


Tím je menu hotové v celé jeho kráse. Nakonec můžeme přidat ještě velice jednoduché podmenu např. pro položuk E-mail, kde bude na výběr ze dvou obrázků vedle sebe. To uděláme tak, že nastavíme Break (zalomení) na bmBreak. Vytvoříme si pro ně proceduru OnMeasureItem, ve které jim nastavíme velikost 50x50 pixelů. Také proceduru OnDrawItem musíme vytvořit znovu, ale jelikož kreslíme pouze obrázek, ne žádný text, je to otázka chvilky. zde vidíte menu s celé své kráse.


A to je pro dnešek vše. Doufám, že se vám menu líbí, protože používat stále stejné je opravdu nudné, a jinak vám aplikaci nezkrášlí :)

Download
ZDE si můžete stáhnout dnes vytvořený program a jeho zdrojáky (172 kB)

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: