17. Nabφdka I
  1. Na╣e seznamovßnφ s nabφdkou budeme provßd∞t na dokonΦenφ aplikace Zßpisnik. Nßvrhß° nabφdky umo╛≥uje rychlΘ vytvo°enφ nabφdky. Hlavnφ nabφdka je tvo°ena komponentou MainMenu. Ka╛d² prvek nabφdky je instance t°φdy MenuItem. Nemusφme se zab²vat tφm, jak tyto t°φdy pracujφ, nebo╗ Nßvrhß° nabφdky vytvß°enφ nabφdky usnad≥uje.

  2. Nejprve musφme p°idat na formulß° komponentu MainMenu. Otev°eme projekt prototypu aplikace Zßpisnφk (vytvo°en² v p°edchozφch kapitolßch). Na formulß° vlo╛φme (kamkoliv) komponentu MainMenu a zm∞nφme jejφ vlastnost Name na Nabidka. Pov╣imn∞te si, ╛e tato komponenta mß velmi mßlo vlastnostφ a ╛ßdnou udßlost. V╣echna prßce nabφdky je soust°ed∞na do jednotliv²ch prvk∙ nabφdky. Dvojit²m kliknutφm na vlo╛enΘ komponent∞ MainMenu zobrazφme Nßvrhß° nabφdky. Nßvrhß° nabφdky vypadß jako prßzdn² formulß° bez rastru. M∙╛eme zm∞nit jeho velikost. Nßvrhß° nabφdky v╛dy udr╛uje volnΘ mφsto pro nov∞ vytvß°en² prvek nabφdky. Kdy╛ poprvΘ Nßvrhß° nabφdky spustφme, pak je vybrßn prßzdn² prvek. Zm∞nφme jeho vlastnost Name na NabSoubor a vlastnost Caption na &Soubor. Znak & je pou╛it pro podtr╛enφ nßsledujφcφho znaku textu prvku nabφdky (urychlovacφ klßvesa). V na╣em p°φpad∞ bude v nabφdce zobrazeno Soubor.
    Nabφdka Soubor je nynφ zobrazena v Nßvrhß°i nabφdky a takΘ na hlavnφm formulß°i (je p°ekryt² nßvrhß°em). Nabφdka na formulß°i je od palety nßstroj∙ odd∞lena komponentou Bevel. V nßvrhß°i nabφdky nynφ vidφme dv∞ volnß mφsta (jedno pod vlo╛en²m prvkem a druhΘ napravo od n∞j). P°ejdeme na spodnφ volnΘ mφsto (Inspektor objekt∙ zobrazuje prßzdnou komponentu MenuItem a Φekß na zadßnφ Name a Caption. Vlastnost Name zm∞nφme na SouborNovy a Caption na &Nov² a stiskneme Enter. Pod vlo╛en²m prvkem nabφdky v Nßvrhß°i nabφdky je op∞t vytvo°en prßzdn² prvek. Obdobn²m zp∙sobem vytvo°φme tyto dal╣φ prvky nabφdky: Otev°φt, Ulo╛it a Ulo╛it jako. Na vhodnß mφsta text∙ vlo╛te i znaky &. Kdykoliv se m∙╛eme vrßtit zp∞t a opravit p°φpadnΘ chyby. Je takΘ vhodnΘ dodr╛ovat standardnφ konvence. Nap°. kdy╛ volba prvku v nabφdce zobrazuje dialogovΘ okno, pak text prvku nabφdky by m∞l konΦit t°emi teΦkami.
    Do nabφdky nynφ pot°ebujeme vlo╛it separßtor (vodorovnou Φßru, kterß odd∞luje prvky nabφdky). Separßtor vlo╛φme obdobn∞ jako libovoln² jin² prvek nabφdky, pouze vlastnost Caption musφ b²t jeden znak pomlΦky. Pod separßtor do nabφdky Soubor vlo╛φme je╣t∞ prvky Tisk a Nastavenφ tiskßrny, dal╣φ separßtor a prvek nabφdky Konec.
    Tφmto zp∙sobem bychom mohli pokraΦovat ve vytvß°enφ dal╣φch nabφdek. Ukß╛eme si ale jinou mo╛nost a to vklßdßnφ nabφdky ze ╣ablony. Standardnφ ╣ablony nabφdky jsou v╣echny v angliΦtin∞ a na╣e nabφdka nebude jazykov∞ konzistentnφ, ale je vhodnΘ v∞d∞t jak pou╛φvat ╣ablonu nabφdky. P°ejdeme na prßzdn² prvek nabφdky napravo od nabφdky Soubor a v mφstnφ nabφdce zvolφme Insert From Template. V zobrazenΘm dialogovΘm okn∞ vidφme seznam dostupn²ch ╣ablon nabφdky. M∙╛eme pou╛φvat p°eddefinovanΘ ╣ablony nebo vytvo°it svoje vlastnφ. Vybereme zde nabφdku Edit a stiskneme OK. Celß nabφdka Edit je vlo╛ena do na╣φ aplikace. Vidφme, ╛e je to snadnΘ. Obdobn∞ je╣t∞ provedeme vlo╛enφ nabφdky Help.
    V p°idan²ch nabφdkßch budeme pot°ebovat provΘst asi n∞jakΘ zm∞ny. Nabφdka Edit obsahuje n∞kterΘ zbyteΦnΘ prvky. Provedeme jejich zru╣enφ. Jednφm ze zbyteΦn²ch prvk∙ je prvek Repeat <comand>. Vybereme jej v Nßvrhß°i nabφdky a stiskneme klßvesu Delete. To je v╣e, prvek je zru╣en. Obdobn∞ zru╣φme prvek Paste Special. V²b∞r prvk∙ v nabφdce lze takΘ roz╣i°ovat (pou╛itφ klßves Ctrl a Shift jako kdy╛ provßdφme v²b∞r v jin²ch aplikacφch). Ukß╛eme si praktickΘ pou╛itφ. Nabφdka Edit stßle obsahuje zbyteΦnΘ prvky. Vybereme zde prvek Goto a p°i stisknutΘ klßvese Shift klikneme na prvek nabφdky Object. Tφm vybereme v╣echny prvky od Goto a╛ k Object. Stiskneme klßvesu Delete a v╣echny vybranΘ prvky zru╣φme najednou. P°ejdeme na nabφdku Help a zru╣φme prost°ednφ dva prvky (z∙stane zde pouze Contents a About).
    Do ji╛ vytvo°enΘ nabφdky je takΘ mo╛no vklßdat novΘ prvky. Vybereme prvek p°ed kter² nov² prvek chceme vlo╛it a stisknneme klßvesu Insert. Tφm vytvo°φme mφsto pro nov∞ vklßdan² prvek. V nabφdce Edit vybereme prvek Find a stiskneme klßvesu Insert. U nov∞ vytvo°enΘ prvku zm∞nφme vlastnost Name na EditSelectAll a Caption na Select &All. P°ejdeme na volnΘ mφsto ve spodnφ Φßsti nabφdky Edit a p°idßme zde separßtor a nov² prvek (Name zm∞nφme na EditWordWrap a Caption na &Word Wrap).
    Prvky nabφdky lze takΘ p°esouvat. K tomuto je mo╛no pou╛φt operacφ se schrßnkou nebo ta╛enφ. P°etßhneme nynφ prvek Select All pod prvek Undo.
    N∞kdy m∙╛eme po╛adovat modifikaci vlastnosti n∞kolika prvk∙ nabφdky najednou. V na╣φ aplikaci zatφm nebudeme implementovat n∞kterΘ funkce (tisk a nßpov∞du). Volby v nabφdce, kterΘ se t²kajφ t∞chto Φinnostφ zakß╛eme. V nabφdce Help vybereme prvek Contents a nastavφme vlastnost Enabled na false. V nabφdce Soubor vybereme oba prvky t²kajφcφ se tisku a op∞t nastavφme vlastnost Enabled na false. Tφm oba prvky zakß╛eme. TotΘ╛ provedeme s prvky Find a Replace v nabφdce Edit.
    V n∞kter²ch p°φpadech takΘ po╛adujeme vytvo°enφ podnabφdky. Podnabφdka je prvek nabφdky, kter² p°i v²b∞ru zobrazφ dal╣φ volby nabφdky. Podnabφdku vytvo°φme tak, ╛e vybereme prvek nabφdky, kter² mß b²t podnabφdkou a p°i stisknutΘ klßvese Ctrl stiskneme klßvesu ╣ipky vpravo. Tφm se vytvo°φ prßzdnΘ mφsto (napravo od vybranΘho prvku) a ve vytvß°enφ podnabφdky postupujeme b∞╛n²m zp∙sobem. V na╣φ aplikaci podnabφdky nebudeme pou╛φvat.
    V nabφdce lze takΘ definovat zkracovacφ klßvesy. Zkracovacφ klßvesa je urΦena vlastnostφ ShortCut. V nabφdce Edit vybereme prvek Select All a zm∞nφme u n∞j vlastnost ShortCut na Ctrl+A. Tφm jsme tomuto prvku p°idali zkracovacφ klßvesu (je zobrazovßna v nabφdce).
    Ve vytvo°enΘ nabφdce provedeme je╣t∞ n∞kterΘ dal╣φ zm∞ny. Prvek Word Wrap slou╛φ k p°epφnßnφ volby zalamovßnφ slov. Implicitn∞ tato volba je zapnutß a bylo by to vhodnΘ indikovat zobrazenφm od╣krtnutφ u tΘto volby. To provedeme nastavenßm vlastnosti Checked na true. Pokud se nßm jmΘna n∞kter²ch prvk∙ nabφdky nelφbφ, pak je m∙╛eme p°ejmenovat. Je vhodnΘ je p°ejmenovat d°φve, ne╛ k nabφdce p°i°adφme k≤d.
    P°ed zahßjenφm vytvß°enφ k≤du na formulß° je╣t∞ umφstφme komponenty OpenDialog a SaveDialog. Nynφ se ji╛ m∙╛eme zab²vat vytvß°enφm obsluh udßlostφ jednotliv²ch voleb v nabφdce. Dvojit²m kliknutφm na prvku nabφdky v Nßvrhß°i nabφdky vytvo°φme kostru obsluhy volby tohoto prvku (obsluha udßlosti OnClick prvku nabφdky). ZaΦneme volbou Konec. Dvojit∞ na nφ klikneme a v Editoru k≤du se objevφ obsluha SouborKonecClick. Do tΘto obsluhy zapφ╣eme p°φkaz
    Close();
    Funkce Close uzavφrß formulß°. Pokud by se na╣e aplikace sklßdala z vφce formulß°∙ a cht∞li bychom ji uzav°φt z libovolnΘho mφsta, pak bychom museli pou╛φt p°φkaz
    Application->Terminate();
    (Close je mo╛no k uzav°enφ aplikace pou╛φt pouze na hlavnφm formulß°i; na jin²ch formulß°φch je zav°en pouze formulß°).
    Dal╣φ jednoduchß obsluha je pro volbu Edit | Cut. Je tvo°ena p°φkazem
    Memo->CutToClipboard();
    Vytvo°φme ji. Dal╣φ jednoduchΘ obsluhy vytvo°te sami (Copy, Paste a Select All). Tyto obsluhy obsahujφ volßnφ metod CopyToClipboard, PasteFromClipboard a SelectAll objektu Memo. Obsluha volby Nov² bude tvo°ena p°φkazy:
    if (Memo->Modified) {
      switch (MessageDlg("SouΦasn² soubor byl zm∞n∞n. Chcete jej ulo╛it?",
        mtConfirmation, TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0)) {
        case mrYes:
          SouborUlozClick(Sender);
          break;
        case mrCancel: return;
      }
    }
    if (Memo->Lines->Count > 0) Memo->Clear();
    SaveDialog1->FileName = "";
    Volßme zde obsluhu volby Ulo╛it. Obsluha volby Otev°φt je tvo°ena p°φkazy:
    if (Memo->Modified) {
      switch (MessageDlg("SouΦasn² soubor byl zm∞n∞n. Chcete jej ulo╛it?",
        mtConfirmation, TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0)) {
        case mrYes:
          SouborUlozClick(Sender);
          break;
        case mrCancel: return;
      }
    }
    OpenDialog1->FileName = "";
    if (OpenDialog1->Execute())
    {
      if (Memo->Lines->Count > 0) Memo->Clear();
      Memo->Lines->LoadFromFile(OpenDialog1->FileName);
      SaveDialog1->FileName = OpenDialog1->FileName;
    }
    Obsluha volby Ulo╛it je tato:
    if (SaveDialog1->FileName != "")
    {
      Memo->Lines->SaveToFile(SaveDialog1->FileName);
      Memo->Modified = false;
    }
    else SouborUlozJakoClick(Sender);
    a obsluha Ulo╛it jako vypadß takto:
    SaveDialog1->Title = "Ulo╛it jako";
    if (SaveDialog1->Execute())
    {
      Memo->Lines->SaveToFile(SaveDialog1->FileName);
      Memo->Modified = false;
    }
    Obsluha WordWrap bude tvo°ena p°φkazy (pokud se provßdφ zalamovßnφ slov, pak je zbyteΦn² vodorovn² posuvnφk):
    Memo->WordWrap = !Memo->WordWrap;
    EditWordWrap->Checked = Memo->WordWrap;
    if (Memo->WordWrap) Memo->ScrollBars = ssVertical;
    else Memo->ScrollBars = ssBoth;
    a poslednφ obsluha tj. Undo, p°φkazem (komponenta Memo nemß metodu Undo, je zapost°edφ zaslat zprßvu Windows, aby tuto operaci provedl):
    SendMessage(Memo->Handle, WM_UNDO, 0, 0);
    Aplikce je hotova. M∙╛eme ji vyzkou╣et. Ukßzali jsme si, jak aplikaci vybavit nabφdkou.
  3. Aplikaci m∙╛eme takΘ vybavit mφstnφ nabφdkou. Mφstnφ nabφdku k n∞kterΘ komponent∞ (ka╛dß komponenta m∙╛e mφt jinou mφstnφ nabφdku) nebo samotnΘmu formulß°i p°i°adφme vlastnostφ PopupMenu komponenty. Nejprve ale mφstnφ nabφdku musφme vytvo°it.

  4. K na╣i p°edchozφ aplikaci (p°esn∞ji jejφ komponent∞ Memo) p°idßme nynφ mφstnφ nabφdku s volbami Cut, Copy a Paste. Na formulß° umφstφme komponentu PopupMenu, zm∞nφme jejφ vlastnost Name na MistniNabidka a dvojit∞ na nφ klikneme. Spustφme tφm Nßvrhß° nabφdky. Volby vklßdanΘ do mφstnφ nabφdky se vyskytujφ v hlavnφ nabφdce a m∙╛eme je tedy p°ekopφrovat. V mφstnφ nabφdce Nßvrhß°e formulß°e zvolφme Select Menu a v zobrazenΘm dialogovΘm okn∞ je uveden seznam nabφdek dostupn²ch z na╣φ aplikace. Zvolφme zde Nabidka a stiskneme OK. Tφm je v Nßvrhß°i nabφdky zobrazena na╣e hlavnφ nabφdka. V nabφdce Edit vybereme prvky Cut, Copy a Paste a stiskem Ctrl+C je p°ekopφrujeme do schrßnky. V mφstnφ nabφdce Nßvrhß°e nabφdky op∞t zvolφme Select Menu a vybereme MistniNabidka (vrßtφme se do vytvß°enΘ mφstnφ nabφdky). Stiskem Ctrl+V obsah schrßnky vlo╛φme do mφstnφ nabφdky. Dßle je nutno zm∞nit vlastnosti Name vlo╛en²ch prvk∙ nabφdky. Zm∞nφme je na PopupCut, PopupCopy a PopupPaste. Poslednφm krokem je vytvo°enφ obsluh udßlostφ voleb mφstnφ nabφdky. Obsluhy jsou ale stejnΘ jako pro obdobnΘ volby hlavnφ nabφdky a m∙╛eme tedy tyto ji╛ vytvo°enΘ obsluhy p°i°adit i prvk∙m mφstnφ nabφdky. U komponenty Memo je takΘ nutno zm∞nit vlastnost PopupMenu na MistniNabidka.
    TlaΦφtka na palet∞ nßstroj∙ jsou zatφm nefunkΦnφ. Je nutno jejφm udßlostem OnClick p°i°adit obsluhy. Je op∞t mo╛no pou╛φt ji╛ vytvo°enΘ obluhy pro volby v hlavnφ nabφdce. Tφm jsme dokonΦili v²voj na╣φ aplikace.
  5. Vid∞li jsme ji╛, jak pou╛φt vytvo°enou ╣ablonu nabφdky. Nynφ se je╣t∞ zmφnφme o tom jak takovouto ╣ablonu vytvo°it. P°i vytvß°enφ ╣ablony nabφdky zaΦneme v²vojem novΘ aplikace a na formulß° umφstφme komponentu MainMenu. V Nßvrhß°i nabφdky nynφ vytvo°φme po╛adovanou nabφdku a volbou Save As Template z mφstnφ nabφdky Nßvrhß°e nabφdky ji ulo╛φme (dßme ji smysluplnΘ jmΘno). Pro zru╣enφ ╣ablony nabφdky v mφstnφ nabφdce Nßvrhß°e nabφdky zvolφme Delete Templates, v zobrazenΘm okn∞ vybereme ru╣enou ╣ablonu a stiskneme OK.
  6. V dal╣φ aplikaci se budeme zab²vat zm∞nami v nabφdce. P°i modifikaci prvku nabφdky se obvykle pou╛φvajφ t°i vlastnosti. Vlastnost Checked pou╛φvßme k p°idßnφ nebo odstran∞nφ znaΦky od╣krtnutφ v prvku nabφdky. Vlastnost Enabled je mo╛no pou╛φt k znev²razn∞nφ prvku nabφdky a u╛ivatel jej potom nem∙╛e zvolit. Dßle m∙╛eme m∞nit vlastnost Caption prvku nabφdky, tzn. zobrazen² text prvku nabφdky. Pou╛itφ t∞chto vlastnostφ si ukß╛eme v tΘto aplikaci. Na formulß° umφstφme dv∞ komponenty GroupBox (nad sebe) a vedle ka╛dΘ z nich umφstφme tlaΦφtko (s textem Ukryj). Do hornφho GroupBox umφstφme dva editaΦnφ ovladaΦe (vlo╛φme do nich n∞jakΘ implicitnφ texty) a zm∞nφme jeho Caption na EditaΦnφ ovladaΦe. Do spodnφho GroupBox umφstφme dv∞ znaΦky a zm∞nφme jeho Caption na ZnaΦky. Na formulß° p°idßme je╣t∞ nabφdku a to podle nßsledujφcφ tabulky (pokud p°i zadßvßnφ vlastnostφ prvk∙ nabφdky zadßvßme pouze Caption, pak vlastnost Name je odvozena ze zadanΘho Caption; vygenerovanß Name jsou ale pon∞kud nesrozumitelnΘ - jsou vynechßna pφsmena s diakritick²mi znamΘnky; tuto mo╛nost pou╛ijeme v tΘto aplikaci):
  7. &Soubor  &TlaΦφtka &Zobrazit  &Nßpov∞da
    &Konec Zaka╛ &prvnφ &EditaΦnφ ovladaΦe &O aplikaci
    Zaka╛ &druhΘ   ZnaΦ&ky
    U prvku nabφdky Zaka╛ prvnφ nastavφme vlastnost Enabled na false a u obou prvk∙ v nabφdce Zobrazit nastavφme Checked na true. Komponenty uvnit° GroupBox se v na╣i aplikaci nevyu╛φvajφ, tlaΦφtka budeme pou╛φvat k zobrazenφ nebo skrytφ jednotliv²ch GroupBox i s ovladaΦi, kterΘ obsahujφ. Stejnou akci je mo╛nΘ provΘst p°φkazy v nabφdce Zobrazit. Poka╛dΘ, kdy╛ zvolφme jeden z t∞chto p°φkaz∙ nebo stiskneme jedno z t∞chto tlaΦφtek, provedou se t°i akce: zm∞nφ se viditelnost p°φslu╣nΘho GroupBox, zm∞nφ se text na tlaΦφtku z Ukryj na Zobraz (nebo naopak) a zm∞nφ se stav od╣krtnutφ prvku nabφdky. Obsluha stisku prvnφho tlaΦφtka a volby EditaΦnφ ovladaΦe bude tedy tvo°ena p°φkazy (pro ob∞ akce pou╛ijte stejnou obsluhu udßlosti; vidφme, ╛e jmΘna prvk∙ nabφdky jsou nesrozumitelnß):
    GroupBox1->Visible = ! GroupBox1->Visible;
    Editanovladae1->Checked = ! Editanovladae1->Checked;
    if (GroupBox1->Visible) Button1->Caption = "Ukryj";
    else Button1->Caption = "Zobraz";
    Obdobn∞ vytvo°te i obsluhu udßlosti pro druhΘ tlaΦφtko a volbu ZnaΦky. Dßle se budeme zab²vat volbami v nabφdce TlaΦφtka. Zßkladnφ my╣lenkou je, aby tyto volby m∞nily text podle provßd∞nΘ akce. Toho dosßhneme nap°. obsluhou:
    if (Button1->Enabled){
      Button1->Enabled = false;
      Zakaprvn1->Caption = "Povol &prvnφ";
    } else {
      Button1->Enabled = true;
      Zakaprvn1->Caption = "Zaka╛ &prvnφ";
    }
    Situace je ale slo╛it∞j╣φ proto╛e po╛adujeme, aby druhΘ tlaΦφtko mohlo b²t povoleno, pouze pokud je povoleno prvnφ tlaΦφtko. Mohou b²t tedy povoleny ob∞ tlaΦφtka, ╛ßdnΘ tlaΦφtko nebo prvnφ povoleno a druhΘ zakßzßno. Kdy╛ jsou ob∞ tlaΦφtka povolena, zakß╛eme volbu nabφdky Zaka╛ prvnφ, Φφm╛ zabrßnφme u╛ivateli v zakßzßnφ prvnφho tlaΦφtka. Kdy╛ jsou zakßzßna ob∞ tlaΦφtka, zakß╛eme volbu nabφdky Zaka╛ druhΘ, Φφm╛ zabrßnφme v povolenφ pouze druhΘho tlaΦφtka. P°edchozφ obsluhu tedy nahradφme obsluhou:
    if (Button1->Enabled){
      Button1->Enabled = false;
      Zakaprvn1->Caption = "Povol &prvnφ";
      Zakadruh1->Enabled = false;
    } else {
      Button1->Enabled = true;
      Zakaprvn1->Caption = "Zaka╛ &prvnφ";
      Zakadruh1->Enabled = true;
    }
    Obsluha volby Zaka╛ druhΘ je obdobnß
    V tΘto aplikaci se zab²vßme zm∞nou prvku nabφdky. Mohli bychom takΘ zneviditelnit prvek nabφdky zm∞nou hodnoty vlastnosti Visible na false. Je ale vhodnΘ tuto operaci nepou╛φvat. Dopl≥te zb²vajφcφ obsluhy a aplikaci vyzkou╣ejte. V tΘto aplikaci vidφme, ╛e vlastnosti Name jednotliv²ch prvk∙ nabφdek jsou pon∞kud ?neΦitelnΘ. Je vhodnΘ je m∞?.
  8. Vlastnost Visible je mo╛no pou╛φvat ke zm∞n∞ viditelnosti jednotliv²ch nabφdek. M∙╛eme si vybrat mezi zakßzan²mi nebo neviditeln²mi nabφdkami. Druh² p°φstup je Φast∞j╣φ. Do nabφdky p°edchozφ aplikace doplnφme dal╣φ nabφdku Nabφdky s volbami: ?Odstra≥ soubor?, ?Odstra≥ nßpov∞du?, ?Zaka╛ tlaΦφtka? a ?Zaka╛ zobrazit?. Obsluha prvnφ volby bude tvo°ena p°φkazy:

  9. Soubor1->Visible = ! Soubor1->Visible;
    Odstrasoubor1->Checked = ! Odstrasoubor1->Checked;
    Vytvo°te zb²vajφcφ obsluhy a aplikaci vyzkou╣ejte.
  10. V jednΘ aplikaci m∙╛eme takΘ st°φdat n∞kolik nabφdek. Pokusφme se to vyzkou╣et. Vytvo°φme aplikaci, ve kterΘ na formulß° vlo╛φme dv∞ komponenty MainMenu (pro ka╛dou z t∞chto komponent navrhneme jinou nabφdku). Prßv∞ pou╛φvanß nabφdka formulß°e je urΦena vlastnostφ Menu formulß°e. M∙╛eme tedy v prvnφ nabφdce mφt prvek nabφdky s obsluhou:

  11. Form1->Menu = MainMenu2;
    Volbou tohoto prvku zobrazφme druhou nabφdku. Obdobn∞ v druhΘ nabφdce budeme mφt volbu pro zobrazenφ prvnφ nabφdky. DokonΦete tuto aplikaci a vyzkou╣ejte.
  12. P°ed na╣φm seznamovßnφm s nabφdkou jsme vytvo°ili aplikaci, kde jsme my╣φ kreslili na formulß°i Φtverce a kruhy. Nynφ k tΘto aplikaci p°idßme nabφdku pro volbu barvy tvar∙ a jejich okraj∙ (tφm se myslφ barva ╣t∞tce a pera) a pro v²b∞r velikosti tvaru a jeho okraje. Na╣i aplikaci vybavφme touto nabφdkou (urychlovacφ klßvesy si dopl≥te sami; dopl≥ujte je takΘ v dal╣φch aplikacφch):
  13. Soubor  Barva Velikost Nßpov∞da
    Nov² Pero Zv∞t╣it ╣φ°ku pera  O aplikaci
    ----- ⌐t∞tec  Zmen╣it ╣φ°ku pera
    Konec ------------------
    Zv∞t╣it velikost tvaru
    Zmen╣it velikost tvaru
    Formulß° inicializuje a uklßdß pouze souΦasn² polom∞r kruhu (tato hodnota se takΘ pou╛φvß jako polovina strany Φtverce), ostatnφ hodnoty jsou ulo╛eny ve vlastnostech plßtna (Canvas). Jako soukromou polo╛ku formulß°e tedy p°idßme:
    int Polomer;
    Pro zm∞nu barev pou╛ijeme komponentu ColorDialog. Budeme se takΘ sna╛it, aby rozm∞ry nebyly zßpornΘ. Obsluha udßlosti OnCreate formulß°e bude tvo°ena p°φkazem:
    Polomer = 5;
    Obsluhu udßlosti OnMouseDown zm∞nφme pouze tak, ╛e namφsto konstant 10 pou╛ijeme polo╛ku Polomer. Obsluha udßlosti OnMouseMove z∙stane beze zm∞ny. Obsluha volby v nabφdce Barva | Pero bude tvo°ena p°φkazy:
    ColorDialog1->Color = Canvas->Pen->Color;
    if (ColorDialog1->Execute()) Canvas->Pen->Color = ColorDialog1->Color;
    Obdobn∞ vy°e╣φme i zm∞nu barvy ╣t∞tce (Brush). Obsluha volby Velikost | Zmen╣it ╣φ°ku pera bude:
    Canvas->Pen->Width = Canvas->Pen->Width - 2;
    if (Canvas->Pen->Width < 3) Zmenitkupera1->Enabled = false;
    a obsluha volby Velikost | Zv∞t╣it ╣φ°ku pera bude:
    Canvas->Pen->Width = Canvas->Pen->Width + 2;
    Zmenitkupera1->Enabled = true;
    Obdobn∞ vy°e╣te volby zm∞ny velikosti tvaru (polo╛ky Polomer). Tuto hodnotu m∞≥te s krokem 5. Volbou Nßpov∞da | O aplikaci zobrazte okno zprßv funkcφ ShowMessage (zobrazte zde nßzev aplikace a svoje jmΘno). Obsluha volby Soubor | Konec bude tvo°ena p°φkazem:
    Close();
    Zb²vajφcφ nevy°e╣enß volba v nabφdce (Soubor | Nov²). Je tvo°ena p°φkazem:
    Refresh();
    Tato metoda p°ekreslφ celΘ okno a sma╛e jeho obsah. Tφm ale ztratφme svoji kresbu. Aplikaci vyzkou╣ejte.
  14. P°edchozφ aplikace mß stßle ten nedostatek, ╛e p°ekrytφm okna nebo zmen╣enφm jeho velikosti ztrßcφme jeho obsah. Nynφ se tento problΘm pokusφme vy°e╣it. Nejprve se ale musφme seznßmit s tφm, co je ve Windows kreslenφ a malovßnφ. Kreslenφ (drawing) je to, co jsme zatφm provßd∞li v na╣i aplikaci (aplikace nevφ jak vytvo°en² obrßzek p°ekreslit). Malovßnφ (painting) je to, co musφme d∞lat, aby aplikace p°ekreslila za jak²chkoli podmφnek nakreslen² obrßzek. Jestli╛e nabφdneme metodu pro p°ekreslenφ obsahu formulß°e (obsluha udßlosti OnPaint), pak tato metoda je automaticky volßna, kdy╛ Φßst formulß°e byla skryta a pot°ebuje p°ekreslit.

  15. Vy°e╣enφ na╣eho problΘmu spoΦφvß v uklßdßnφ informacφ o nakreslen²ch tvarech a vytvo°enφ obsluhy udßlosti OnPaint, ve kterΘ na╣e tvary zobrazφme. Pro uklßdßnφ informacφ o nakreslenΘm tvaru si vytvo°φme novou strukturu:
    struct TTvar {
      bool Kruznice;
      int X, Y, Velikost, PeroSire;
      TColor BarvaPera, BarvaStetce;
    };
    Deklaraci tΘto struktury umφstφme do hlaviΦkovΘho souboru formulß°e p°ed deklaraci typu formulß°e. Prom∞nnΘ tΘto struktury (popisujφcφ jednotlivΘ tvary) budeme uklßdat do seznamu (standardnφ t°φda TList). Tento seznam nazvan² SeznamTvaru je soukromß polo╛ka formulß°e a je inicializovßna v obsluze udßlosti OnCreate formulß°e:
    Polomer = 5;
    SeznamTvaru = new TList;
    Tvar do seznamu budeme p°idßvat v obsluze udßlosti OnMouseDown a po p°idßnφ tvaru do seznamu v╛dy provedeme p°ekreslenφ. Tato udßlost bude nynφ obsahovat p°φkazy:
    TTvar *Tvar;
    if (Button == mbLeft) {
      Tvar = new TTvar;
      Tvar->Kruznice = ! Shift.Contains(ssShift);
      Tvar->X = X;
      Tvar->Y = Y;
      Tvar->Velikost = Polomer;
      Tvar->PeroSire = Canvas->Pen->Width;
      Tvar->BarvaPera = Canvas->Pen->Color;
      Tvar->BarvaStetce = Canvas->Brush->Color;
      SeznamTvaru->Add(Tvar);
      Repaint();
    }
    Aby probφhalo p°ekreslovßnφ, je nutno vytvo°it obsluhu udßlosti OnPaint:
    TTvar *Tvar;
    Tvar = new TTvar;
    for (int I=0; I < SeznamTvaru->Count; I++){
      Tvar = (TTvar *)SeznamTvaru->Items[I];
      Canvas->Pen->Color = Tvar->BarvaPera;
      Canvas->Pen->Width = Tvar->PeroSire;
      Canvas->Brush->Color = Tvar->BarvaStetce;
      if (Tvar->Kruznice) Canvas->Ellipse(Tvar->X-Tvar->Velikost,
                Tvar->Y-Tvar->Velikost,Tvar->X+Tvar->Velikost,
                Tvar->Y+Tvar->Velikost);
      else Canvas->Rectangle(Tvar->X-Tvar->Velikost,
                Tvar->Y-Tvar->Velikost,Tvar->X+Tvar->Velikost,
                Tvar->Y+Tvar->Velikost);
    }
    delete Tvar;
    V tΘto obsluze jsou vykresleny v╣echny tvary uvedenΘ v seznamu (poΦet prvk∙ seznamu je urΦen Count a p°istupujeme k nim indexovßnφm vlastnosti Items). Musφme je╣t∞ zm∞nit obsluhu volby nabφdky Soubor | Nov² a to takto:
    if (SeznamTvaru->Count > 0)
      if (MessageDlg("Chcete opravdu zru╣it v╣echny tvary?",
          mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes){
        SeznamTvaru->Clear();
        Refresh();
      }
    Aplikaci vyzkou╣ejte. P°idejte je╣t∞ volbu nabφdky pro zm∞nu barvy formulß°e.
  16. Komponenta Image je obvykle pova╛ovßna za zobrazovaΦ obrßzk∙. Vytvo°φme nynφ aplikaci pro zobrazovßnφ obrßzk∙. Na formulß° umφstφme komponentu Image (bude zabφrat celou plochu formulß°e) a vytvo°φme nßsledujφcφ nabφdku:
  17. Soubor Volby Nßpov∞da
    Otev°φt Zaplnit O aplikaci
    ----- Centrovat
    Konec
    Obsluhu voleb Konec a O aplikaci si vytvo°te sami. Volba Otev°φt bude tvo°ena k≤dem:
    if (OpenDialog1->Execute()){
      Image1->Picture->LoadFromFile(OpenDialog1->FileName);
      Caption = "Obrßzek: " + OpenDialog1->FileName;
    }
    Na formulß° musφme tedy vlo╛it i komponentu OpenDialog, kde nastavφme vlastnosti Filter na BitovΘ mapy (*.bmp), Ikony (*.ico) a MetaSoubor (*.wmf) a Options na [ofHideReadOnly, ofPathMustExist, ofFileMustExist]. Zjist∞te, co tyto volby znamenajφ. Volba nabφdky Zaplnit bude tvo°ena p°φkazy:
    Image1->Stretch = ! Image1->Stretch;
    Zaplnit1->Checked = Image1->Stretch;
    a volba Centrovat p°φkazy:
    Image1->Center = ! Image1->Center;
    Centrovat1->Checked = ! Image1->Center;
    Nynφ ji╛ aplikaci m∙╛eme vyzkou╣et. Zjist∞te, co provßd∞jφ jednotlivΘ volby nabφdky.
  18. Poslednφ dv∞ aplikace nynφ spojφme dohromady. M∙╛eme naΦφst existujφcφ bitovou mapu, nakreslit p°es nφ n∞kolik tvar∙ a v²sledek ulo╛it do souboru. V tΘto aplikaci pou╛ijeme p°edposlednφ verzi aplikace kreslenφ tvar∙ (informace o nakreslen²ch tvarech nemusφme uklßdat, nebo╗ jsou vlo╛eny p°φmo do bitovΘ mapy). V╣echny v²stupnφ operace t²kajφcφ se plßtna formulß°e musφme zm∞nit na plßtno komponenty Image (nap°. Image1->Canvas->Pen->Color). Aplikace bude mφt nabφdku:
  19. Soubor  Barva Velikost  Nßpov∞da
    Nov² Pero Zv∞t╣it ╣φ°ku pera O aplikaci
    Otev°φt ⌐t∞tec Zmen╣it ╣φ°ku pera
    Ulo╛it jako ------------------
    ----- Zv∞t╣it velikost tvaru
    Konec Zmen╣it velikost tvaru
    Volba Barva | Pero bude tedy obsahovat p°φkazy:
    ColorDialog1->Color = Image1->Canvas->Pen->Color;
    if (ColorDialog1->Execute())
      Image1->Canvas->Pen->Color = ColorDialog1->Color;
    Volba Ulo╛ jako bude tvo°ena p°φkazem:
    if (SaveDialog1->Execute())
      Image1->Picture->SaveToFile(SaveDialog1->FileName);
    U komponenty SaveDialog musφme nastavit tyto vlastnosti: DefaultExt na BMP, FileName na Tvary.bmp, Filter na Soubory bitovΘ mapy (*.bmp) a Options na [ofOwerwritePromtp, ofHideReadOnly, ofPathMustExist, ofFileMustExist]. U komponenty OpenDialog nastavφme vlastnosti: DefaultExt na BMP, Filter na Soubory bitovΘ mapy (*.bmp) (v tΘto aplikaci je mo╛no pou╛φvat pouze soubory bitov²ch map) a Options na [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofShareAware]. Musφme samoz°ejm∞ ulo╛it p∙vodnφ barvu a po otev°enφ bitovΘ mapy ji obnovit. To vy°e╣φme v obsluze volby Otev°φt takto:
    if (OpenDialog1->Execute()){
      TColor BPera = Image1->Canvas->Pen->Color;
      TColor BStetce = Image1->Canvas->Brush->Color;
      int SirePera = Image1->Canvas->Pen->Width;
      Image1->Picture->LoadFromFile(OpenDialog1->FileName);
      Caption = "Obrßzek: " + OpenDialog1->FileName;
      Image1->Canvas->Pen->Color = BPera;
      Image1->Canvas->Brush->Color = BStetce;
      Image1->Canvas->Pen->Width = SirePera;
    }
    Za zmφnku stojφ je╣t∞ obsluha volby Nov². Zde je nutno plochu komponenty Image vybarvit bφlou barvou. To provedeme takto:
    if (MessageDlg("Chcete opravdu zru╣it v╣echny tvary?",
        mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes){
      TRect Oblast=Rect(0,0,Image1->Picture->Width,Image1->Picture->Height);
      TColor Barva = Image1->Canvas->Brush->Color;
      Image1->Canvas->Brush->Color = clWhite;
      Image1->Canvas->FillRect(Oblast);
      Image1->Canvas->Brush->Color = Barva;
    }
    Ostatnφ obsluhy udßlostφ nepot°ebujφ ╛ßdnΘ vysv∞tlenφ. Vytvo°te je sami a aplikaci vyzkou╣ejte.
17. Nabφdka I