Tipy a triky v Delphi, díl 152. - formuláře

Na minulý díl o formulářích dnes nenápadně navážeme, protože se mi hromadí dotazy na toto téma. Opět se jedná o základní postupy, které však mnozí začínající uživatelé (zvlášť samouci) neznají.

Dnes si tedy opět budeme povídat o formulářích. Začínající programátor v Delphi, obvykle samouk a fanoušek, je často stržen jednoduchostí, s jakou lze některé aplikace vytvářet. Zapomíná pak nahlédnout hlouběji "pod pokličku", protože jeho aplikace funguje a nemá důvod něco měnit. Změna nastane až tehdy, když chce vytvářet programy komplikovanější a kromě jednoho hlavního okna (formuláře) chce mít i okna podřízená. Pak nastanou první problémy. Například s tím, jak mezi jednotlivými okny aplikace předávat hodnoty proměnných. O tom i o dalších souvisejících problémech bude dnešní a příští díl.

Jak přidat do projektu další formulář je snadné a kromě hlavního okna pak aplikace může obsahovat prakticky "neomezené" množství dalších oken. I jejich vyvolání například metodou Show je bezproblémové. Základní projektový soubor v případě jednoho hlavního a dvou podřízených formulářů pak vypadá nějak takto:

program Project1;

uses
  Forms,
  Unit1 in `Unit1.pas` {Form1}
  Unit2 in `Unit2.pas` {Form2}
  Unit3 in `Unit3.pas` {Form3}

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.CreateForm(TForm3, Form3);
  Application.Run;
end.

Potud je všechno jasné, aplikace funguje. Co se dá tedy vylepšit? Jak vidíme ve zdrojovém kódu projektu, všechny formuláře jsou metodou CreateForm vytvořeny hned na začátku. V reálné aplikaci ale málokdy potřebujeme mít všechny formuláře vytvořeny hned. Jsou okna, která zahlédneme při používání aplikace stěží jednou (například okno s konfigurací aplikace po prvním spuštění programu po instalaci) a těch opravdu používaných (viditelných) oken může být jen pár. Proč tedy vytvářet třeba velké množství oken hned při startu? Není to zbytečné plýtvání systémovými zdroji? Jistě, v dnešní době operačních systémů generace NT už to není tak problematická záležitost, ale přesto by bylo dobré zvyknout si na určitou míru optimalizace a nespoléhat se jen na robustnost systému. Okna tedy budeme vytvářet dynamicky až tehdy, kdy budou potřeba.

Nejprve tedy ze zdrojového kódu projektu odstraníme řádky, kde jsou vytvářena sekundární okna, případně provedeme tuto úpravu jen u některých oken, kde to má smysl (viz. předchozí odstavec). Můžeme to udělat ručně přímo editací zdrojového kódu a nebo přes nabídku Project -> Options a zde na záložce Forms v seznamu Auto-create forms odstraníme (resp. uklidíme šipkami do sekce Available forms) příslušné formuláře.

Mimochodem, všimli jste si, že o tom, který z formulářů projektu bude ten hlavní, rozhoduje jen jejich pořadí? Nic jiného v tom není. Stačí prohodit na první místo například Form2 (buď opět přímo ve zdrojáku a nebo metodou drag & drop ve zmiňované nabídce) a při spuštění aplikace bude hlavním formulářem. A pro zvídavé čtenáře ještě jeden tip. Zkuste tímto způsobem uklidit všechny formuláře, tj. žádný nebude vytvářen hned po startu aplikace. Co se stane? Nic neočekávaného. Aplikace se prostě spustí a hned se zase ukončí.

Takže, teď se nám po startu aplikace vytvoří jen ty nejdůležitější formuláře (klidně jen ten hlavní). O vytvoření těch ostatních se musíme postarat sami dynamicky za běhu aplikace.

Prvním krokem, který k tomu vede, je to, že musíme přidat do řádku uses (v části implementation) u hlavního formuláře (resp. obecně u toho formuláře, ze kterého voláme jiný) příslušný unit volaného formuláře. V našem případě to bude Unit2. K vlastnímu vytvoření druhého formuláře nám pak poslouží tlačítko, které umístíme na hlavní formulář a příslušný kód vložíme do události OnClick.

Pro zobrazení podřízeného okna máme vlastně dvě možnosti. Buď jej můžeme zobrazit "normálně", takže okno je více či méně rovnocenné oknu hlavnímu, nebo modálně. Modální okno, jak jistě víte, překryje všechno okna dané aplikace a dokud okno není uzavřeno, nelze překliknout do oken jiných (v rámci aplikace). Používají se obvykle pro důležitá dialogová okna, kde pro další běh programu je bezpodmínečně nutné rozhodnutí uživatele.

Začneme tou jednodušší variantou, což je zobrazení modální. V takovém případě nám stačí následující procedura:

procedure TForm1.Button1Click(Sender: TObject);
var
  f: TForm2;
begin
  f := TForm2.Create(Self);
  try
    f.ShowModal;
  finally
    f.Release;
  end;
end;

Jak vidíte, postup je velmi snadný. Potřebujeme pouze nadeklarovat proměnnou typu TForm2 (tedy náš připravený druhý formulář) a metodou Create ho vytvořit. Jediným parametrem tohoto konstruktoru je vlastník nově vznikajícího formuláře. Hodnota Self říká, že to bude náš hlavní formulář. Poté již jen okno zobrazíme metodou ShowModal a po jeho uzavření objekt zaniká metodou Release.

Druhá možnost je zobrazit okno klasickým nemodálním způsobem. Ihned se nám nabízí myšlenka použít stejný kód a nahradit pouze metodu ShowModal metodou Show. Bohužel, tak snadné to není a věc má hned dvě úskalí. Pokud totiž takový kód spustíte, okno se sice na moment zobrazí, ale hned se zase uzavře. Nečeká se totiž na žádnou reakci uživatele jako v případě modálního okna, takže metoda Release je spuštěna ihned po Show. Řešení je jednoduché. V hlavním okně budeme podřízený formulář "jen" zobrazovat a o jeho následný úklid se pak postará podřízený formulář sám v metodě OnClose.

procedure TForm1.Button2Click(Sender: TObject);
var
  f: TForm2;
begin
  f := TForm2.Create(Self);
  f.Show;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree ;
end;

Druhý problém může být problémem jen v určitém případě, záleží čistě na stavbě vaší aplikace. Zobrazíme-li totiž například pomocí tlačítka druhý formulář nemodálně, nic nám nebrání po jeho zobrazení překliknout zpět do hlavního formuláře a tlačítko stisknout znovu. Co se stane? Celkem nic tragického, bude vytvořena další instance druhého formuláře. To ale někdy může dost vadit a proto si ještě na závěr ukážeme, jak tento problém přelstít.

Myšlenka je celkem zřejmá. Než vytvoříme danou instanci druhého formuláře, přesvědčíme se jednoduchým cyklem, zda již náhodou neexistuje. Pokud ano, přepneme zobrazení na něj, pokud ne, vytvoříme jej.

procedure TForm1.Button2Click(Sender: TObject);
var
  f: TForm2;
  i, ex: integer;
begin
  ex := -1;
  for i := 0 to Screen.FormCount -1 do
    if Screen.Forms[i] is TForm2 then ex := i;
  if ex >= 0 then Screen.Forms[ex].Show
            else
              begin
                f := TForm2.Create(Self);
                f.Show;
              end;
end;

To by tedy mohlo pro dnešek stačit. Teď už tedy víme, že formuláře můžeme z úsporných důvodů vytvářet až dynamicky za běhu aplikace (i když připravené je máme z Delphi IDE pochopitelně již předem) a není k tomu ani potřeba příliš mnoho kódu navíc. Jistá nevýhoda je samozřejmě pomalejší reakce při zobrazení takového okna, protože musí být nejprve vytvořeno. Tento problém by ale mohl být patrný maximálně na opravdu velmi pomalých a starých počítačích. Dnešní ukázkový projekt můžete stahovat zde.

Příště si povídání o formulářích dokončíme a řekneme si něco o jejich vzájemné interakci, předávání hodnot a podobně.

Váš názor Další článek: New York bude kompletně pokryt bezdrátovou sítí

Témata článku: Software, Programování, Druhý případ, TRI, Formulář, Self, Zbytečné plýtvání, Jediný parametr, Trik, Okno, Úsporný důvod, Díl, Show, DEL, Související problém


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

Nový Apple Macbook Air je levnější, má větší SSD a vrací se k tradiční klávesnici

Nový Apple Macbook Air je levnější, má větší SSD a vrací se k tradiční klávesnici

** Nový MacBook Air opravuje nejzásadnější chyby dosavadní verze ** Dostal lepší klávesnici, výkonnější procesor a 256GB SSD ** Apple navíc snížil ceny

Martin Miksa | 53

Galerie: Podívejte se na čínský Linux, se kterým to na svých PC zkusil i Huawei

Galerie: Podívejte se na čínský Linux, se kterým to na svých PC zkusil i Huawei

** Huawei se loni dostal do křížku s USA ** Začal to proto zkoušet s konkurenčním operačním systémem ** Jmenuje se Deepin a před pár dny se dočkal nové verze

Jakub Čížek | 36

Šmírování kamerami Googlu: Koukněte, co šíleného se objevilo na Street View

Šmírování kamerami Googlu: Koukněte, co šíleného se objevilo na Street View

Google stále fotí celý svět do své služby Street View. A novodobou zábavou je hledat v mapách Googlu vtipné záběry. Podívejte se na výběr nejlepších!

redakce | 1

10 věcí, které jste odkládali „na jindy“, ale teď je konečně můžete udělat

10 věcí, které jste odkládali „na jindy“, ale teď je konečně můžete udělat

** Karanténní opatření nás drží doma a mnozí mají více času navíc ** Připomeneme proto často odkládané činnosti uživatelů počítačů ** Právě teď je ten správný okamžik, kdy se do nich pustit

Karel Kilián | 75


Aktuální číslo časopisu Computer

Megatest 24 PC zdrojů

Jak využít umělou inteligenci

10 špičkových sluchátek s ANC

Playstation 5 vs Xbox Series X