Vytváření dočasných komponent za běhu

vložil Radek Červinka 2. června 2012 00:54

Mějme klasický kód, tj. vytvoříme dynamicky za běhu formulář a modálně ho zobrazíme.

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TForm2.Create(Application) do
  begin
    try
      ShowModal;
    finally
      Free;
    end;
  end;
end;

Nepovažuji se za nejostřejší nůž v šuplíku a tudíž se možná pletu, ale je zde malé ale.

Jak všichni víme, constructor Create pro komponenty obsahuje parametr Owner: TComponent, tj. předáním existující komponenty jednoduše přehodíme odpovědnost za uvolnění nové komponenty na předanou komponentu. Tj. při uvolnění nadřazené (předané) komponenty, destruktor uvolní všechny vlastněné komponenty. Což je velmi vhodné využívat a považuji to za velmi geniální myšlenku.

Ale zpět k našemu případu. V příkladu předáváme Application. Destructor pro TComponent obsahuje následující kód:

  if FOwner <> nil then FOwner.RemoveComponent(Self);

a v RemoveComponent je

procedure TComponent.RemoveComponent(AComponent: TComponent);
begin
  ValidateRename(AComponent, AComponent.FName, '');
  Notification(AComponent, opRemove);
  AComponent.SetReference(False);
  Remove(AComponent);
end;

Všimněte si řádku s Notification. Existuje spousta komponent, které naslouchají na Notification a provádějí všelijaké akce. V tomto případě úplně zbytečně.

Chci tím naznačit, že specifikovat vlastníka v případě, že sami uvolňujeme není zas až tak dobrý nápad. Nebo se pletu?

Mimochodem: dá se nějak zaručit, aby se při přepínání aplikací vždycky zobrazilo naše zobrazené modální okno (nebo hláška)? Už se mi v extrémních případech stalo, že nešel dialog vidět (po přepnutí).

Tagy: ,

Praxe

Komentáře

2.6.2012 9:47:37 #

sso

zdravím,
problém zobrazení modálního okna řeším občas taky. zatím co jsem vysledoval tak se to děje když showmodal je spuštěno když aplikace není aktivní. U mně konkrétně to je: mám modální okno1, z něj tlačítkem spouštím  nějaký dlouhý kod, na jehož konci je showmodal dalšího okna2('HOTOVO');. před dokončením toho dlouhého kodu se přepnu do jiné aplikace, když se vrátím do své aplikace kliknutím myší na hlavní panel tak se občas stane že to modální okno2 není vidět, ale je vidět okno1. Ale OKNO2 je aktivní, protože aplikace nereaguje, ale je skryto za oknem 1 nebo možná i za mainform. Pokud se do své aplikace vrátím přes ALT+TAB tak to funguje správně vždy.
Snad jsem to napsal pochopitelně:)

řeší se např i na:
- http://forum.builder.cz/read.php?18,2687012,2687135#msg-2687135
- http://stackoverflow.com/questions/1639125/form-is-hidden-behind-other-forms-when-showmodal-is-called

sso

2.6.2012 11:51:41 #

sso

ještě závěr:
i přes různé rady a návody jsem funkční řešení problému zatím nenašel

sso

2.6.2012 18:01:53 #

PS

@parent: Nastavovať parent na form je vhodné, teda pokiaľ tam má byť nejaká pozičná logika (ak sa nechceme ručne hrajkať s pozíciou ale použiť poOwnerFormCenter).

@modal vždy hore:
    procedure CreateParams(var Params: TCreateParams);override;

procedure TForm.CreateParams(var Params: TCreateParams);
begin
  Inherited;
  Params.ExStyle := params.ExStyle or WS_EX_CONTROLPARENT;
  Params.Style := params.Style or WS_TABSTOP or WS_POPUPWINDOW;
end;

Zatiaľ funguje spolahlivo (XP, Vista, Win7) Delphi XE. Dosť veľké problémy boli v Delphi 6 a hlavný dôvod na upgrade boli odstránené problémy (ALT+TAB nezobrazovanie vo Win7, focus, ..) plus samozrejme Margins :)
Pri formoch ostáva ešte (aj v XE2 :( ) problém s ikonou, ktorú delphi zrušia necitlivo ešte počas zobrazeného okna, a teda ikona sa zmení na nejakú windows default. Čo pri otváraní a zatvárani okien pôsobí dosť rušivo :(

PS

8.6.2012 18:07:26 #

TLama

Owner v konstruktoru instance objektu, o jehož uvolnění se sami postaráme by nikdy neměl být specifikován, tedy přesněji měl by zůstat nil. Následující kód je tedy "správnější":

with TForm2.Create(nil) do
try
  ShowModal;
finally
  Free;
end;

Více např. tady:
http://stackoverflow.com/a/5420443/960757

TLama

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců