Autor Téma: Spuště Form2 s Form1  (Přečteno 6764 krát)

k.k

  • Host
Spuště Form2 s Form1
« kdy: 14-03-2013, 07:02:22 »
Dobry den.
Poradite začatečnikovi.
Muj projekt ma 2 form.
Proč když chci spustit s Form1.FormActivate Form2, vyskoči toto.



Kód: Delphi [Vybrat]
  1. procedure TForm1.FormActivate(Sender: TObject);
  2. begin
  3. Form2.showmodal;
  4. end;


Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #1 kdy: 14-03-2013, 08:02:44 »
Proč když chci spustit s Form1.FormActivate Form2, vyskoči toto.

Kód: Delphi [Vybrat]
  1. procedure TForm1.FormActivate(Sender: TObject);
  2. begin
  3. Form2.showmodal;
  4. end;
Zrejme proto, ze kdyz dostane Form1 focus, tak jeste nebyla vytvorena instance Form2 ( = nil, jak bys urcite zjistil pri pouziti debuggeru)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #2 kdy: 14-03-2013, 09:08:14 »
Kód: Delphi [Vybrat]
  1. procedure TForm1.FormActivate(Sender: TObject);
  2. begin
  3. Form2.showmodal;
  4. end;

Jinak pro Stanislava Hrušku: typická ukázka nevhodnosti používání globálních proměnných

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4992
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Spuště Form2 s Form1
« Odpověď #3 kdy: 14-03-2013, 10:05:54 »
 ;D ;D ;D
Ináč pre tých, čo mi radia. Teraz nerobím nič iné, iba sa zbavujem globálnych premenných. V prípade potreby ich odovzdávam ako parameter. Ten môj zdroják začína byť akosi čitateľnejší/zrozumiteľnejší.
 
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

k.k

  • Host
Re:Spuště Form2 s Form1
« Odpověď #4 kdy: 14-03-2013, 16:38:53 »
Tak poradte, kam mam nacpat to.
Form2.showmodal;
Aby se mi zobrazil Form2 hned po zobrazení Form1.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #5 kdy: 14-03-2013, 16:49:05 »
To není ani tak otázka na to, kam dát Form2.ShowModal, jako spíš na to, kam dát vytvoření instance Form2. Kde ty formuláře vytváříš a jak?

K.K

  • Host
Re:Spuště Form2 s Form1
« Odpověď #6 kdy: 15-03-2013, 06:01:48 »
Tak porad lamě jak na to.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #7 kdy: 15-03-2013, 06:21:10 »
Když ti poradím, "musíš zařídit, aby se ten formulář vytvořil předtím, než se ho pokusíš zobrazit," pomůže ti to? Proto jsem se tě ptal, kde a jak ho vytváříš, pak bych ti mohl poradit přesněji.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #8 kdy: 15-03-2013, 06:24:27 »
A když už se tím budeš zabývat, tak možná rovnou i napiš, čeho bys chtěl dosáhnout (jaký je účel této operace). Ne že by se to nedalo, ale zdá se mi poměrně podezřelé, volat ve FormActivate jednoho formuláře ShowModal druhého - ShowModal bych očekával spíš v reakci na nějaké kliknutí na tlačítko, zobrazování během FormActivate bych zase čekal spíš pomocí Show. Možná se ukáže, že to děláš správně, ale jak říkám, zrovna obvyklé to takhle není.

K.K

  • Host
Re:Spuště Form2 s Form1
« Odpověď #9 kdy: 15-03-2013, 07:50:38 »
Form 2 jsem vytvořil normalně přes project manager.
Zatim to řešim přes ten button ale nelibi.
Form 2 je takovy přihlašovaci.
Zobrazi se Form1 s prazdnym StringGridem a hned by vyskočil Form2 pro zadani informaci.
Nemam rad zbytečne klikani.
Po zadani jmena a hesla se teprve načtou data ve Form1 do StringGridu podle uživatele, ktery se přihlasil.
Netušil jsem že s tym dudou takove problemy.
Hold lama :(

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #10 kdy: 15-03-2013, 08:10:49 »
1) No tak za těchto okolností je vhodné si ten formulář vytvořit sám, použít ho a hned zase zrušit - ne ho vytvořit na začátku programu, jednou použít a pak nechat celou dobu v paměti (patrně i s vyplněným heslem). Takže ten formulář v Project options vyřaď z automatického vytváření a pak si ho vytvářej sám:
Kód: Delphi [Vybrat]
  1. var
  2.   F: TForm2;
  3. begin
  4.   F := TForm2.Create(Self);
  5.   try
  6.     if F.ShowModal = mrOK then ... ;
  7.   finally
  8.     FreeAndNil(F);
  9.     end;
  10. end;

2) FormActivate pro tohle podle mě není vhodné místo. Obvykle se to řeší tak, že si formulář ve FormCreate pošle sám sobě zprávu a v obsluze té zprávy provede příslušnou akci. Například proto, že uživatel to heslo nezná, tak bude chtít přihlašovací formulář ESCAPEm zavřít a očekává, že se aplikace ukončí.
Kód: Delphi [Vybrat]
  1. const
  2.   WM_USER_POVYTVORENIFORMULARE = WM_USER + 1;
  3. type
  4.   TForm1 = class(TForm)
  5.     ...
  6.     public
  7.       constructor Create(AOwner: TComponent); override;
  8.     private
  9.       procedure WMUserPoVytvoreniFormulare(var Msg: TMessage); message WM_USER_POVYTVORENIFORMULARE;
  10.     end;
  11.  
  12. constructor TForm1.Create(AOwner: TComponent);
  13. begin
  14.   inherited Create(AOwner);
  15.   PostMessage(Handle, WM_USER_POVYTVORENIFORMULARE, 0, 0);
  16. end;
  17.  
  18. procedure TForm1.WMUserPoVytvoreniFormulare;
  19. begin
  20.   // Tady uz si delej, co potrebujes
  21. end;

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4992
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Spuště Form2 s Form1
« Odpověď #11 kdy: 15-03-2013, 08:41:59 »
Ja by som najprv vytovril a zobrazil prihlasovací formulár. Až po zadaní správnych údajov by som vytvoril a zobrazil ďalší formulár.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

k.k

  • Host
Re:Spuště Form2 s Form1
« Odpověď #12 kdy: 15-03-2013, 15:29:04 »
 Pepak dik moc za radu, ochotu i ty přiklady.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 576
  • Karma: 25
Re:Spuště Form2 s Form1
« Odpověď #13 kdy: 15-03-2013, 17:56:41 »
Ja by som najprv vytovril a zobrazil prihlasovací formulár. Až po zadaní správnych údajov by som vytvoril a zobrazil ďalší formulár.

to jo, dá se to třeba v .dpr před tím, než se začnou vytvářet ty automaticky vytvářené formuláře

kk

  • Host
Re:Spuště Form2 s Form1
« Odpověď #14 kdy: 16-03-2013, 16:51:22 »
Tak jsem si dnes hral a zkoušel ten druhy zpusob od pepaka.
Fungovat to funguje ale vypada to nějak divně.
První se vykresli Form2.
Pak Form1.
A pak se znovu překresli ten Form2 aby byl nad Form1.

Mam to tak jak to tu dal pepak jen jsem přidal do procedure TForm1.WMUserPoVytvoreniFormulare;

form2.showmodal;

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #15 kdy: 16-03-2013, 19:03:19 »
Tak samozřejmě to nemusíš psát přímo v OnCreate. Zrovna tak dobře bys to mohl dát třeba do OnShow, ideálně tak, že:

Kód: Delphi [Vybrat]
  1. type
  2.   TForm = class(TForm)
  3.     procedure FormCreate(Sender: TObject);
  4.     procedure FormShow(Sender: TObject);
  5.   private
  6.     fForm2UzBylZobrazen: boolean;
  7.   end;
  8.  
  9. procedure TForm1.FormCreate(Sender: TObject);
  10. begin
  11.   fForm2UzBylZobrazen := False; // V podstate zbytecne, promenne se inicializuji na False/0/nil atd., ale pro nazornost
  12. end;
  13.  
  14. procedure TForm1.FormCreate(Sender: TObject);
  15. begin
  16.   if not fForm2UzBylZobrazen then
  17.     begin
  18.     PostMessage(...);
  19.     fForm2UzBylZobrazen := True;
  20.     end;
  21. end;

kk

  • Host
Re:Spuště Form2 s Form1
« Odpověď #16 kdy: 17-03-2013, 07:58:27 »
Tak s toho začinam byt trochu mimo.
Delphi mam jen 3 měsice, takže uplna lama.
Netušil jsem že stym bude takovy problem.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #17 kdy: 17-03-2013, 08:37:38 »
Tak s toho začinam byt trochu mimo.
Delphi mam jen 3 měsice, takže uplna lama.
Netušil jsem že stym bude takovy problem.
Takova kontrolni otazka: v project options | forms jsi zajistil, aby se ti vytvarel jen hlavni form?

A pokud to nefunguje spravne, tak jsi neco udelal jinak, nez ti pepak radil. Jeste jednou rekapitulace:
1. v .dpr vytvaris jediny formular a to hlavni okno
2. Do unit hlavniho okna pridas v implementation do uses LoginForm
3. v OnCreate hlavniho okna si posles na jeho handle nejakou user message (kterou sis tam nadefinoval)
4. v handleru te user message vytvoris instanci login formulare, na ktere zalovas ShowModal a po navratu instanci formulare zrusis

Pokud si zajistis, ze ti Login formular vrati mrOK v pripade, ze bylo prihlaseni uspesne, tak muzes udelat neco takoveho:

Kód: Delphi [Vybrat]
  1. procedure TMainForm.__UM_ShowLogin(var AMsg: TMessage);
  2. var
  3.   Form: TLoginForm;
  4. begin
  5.   Form := TLoginForm.Create(self);
  6.   try
  7.     if Form.ShowModal<>mrOK then
  8.       PostMessage(self.Handle, WM_QUIT, 0, 0);
  9.   finally
  10.     Form.Release;
  11.   end;
  12. end;
  13.  

A proc se to dela: kdyz si posles sam sobe message, tak ji Windows zaradi do fronty, odkud si ji okno, kteremu byla urcena, pozdeji vyzvedne. Klicove je to pozdeji: formular se nejdriv vytvori a zobrazi (uplne probehnou vsechny odalosti OnCreate, OnShow atd.) a teprva pak jde okno cist zpravy z fronty.

Offline Slavomir

  • Mladík
  • **
  • Příspěvků: 58
  • Karma: 0
    • Verze Delphi: XE2 + 10.3 Community Edition
    • RQ Money
Re:Spuště Form2 s Form1
« Odpověď #18 kdy: 17-03-2013, 08:38:53 »
Ja by som to riešil asi trochu jednoduchšie:

1) Vytvorím Form1 a Form2.
2) V procedúre OnShow u Form1 spustím obyčajný Timer, ktorý napr. po pol sekunde spustí Form2.

Používam to, funguje to. Najskôr sa zobrazí Form1 a hneď za ním Form2.
« Poslední změna: 17-03-2013, 08:41:49 od Slavomir »
Lazarus, Delphi - RQ Money

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #19 kdy: 17-03-2013, 08:42:51 »
Ja by som to riešil asi trochu jednoduchšie:
...
Používam to, funguje to. Najskôr sa zobrazí Form1 a hneď za ním Form2.
Urcite to funguje, protoze to dela totez. Ale jestli je to jednoduzsi...

kk

  • Host
Re:Spuště Form2 s Form1
« Odpověď #20 kdy: 17-03-2013, 08:53:12 »
Citace: pf1957
Takova kontrolni otazka: v project options | forms jsi zajistil, aby se ti vytvarel jen hlavni form?
A to jak zajistim.
Určitě v options ale nemohu najit  :(

Citace: Slavomir
Ja by som to riešil asi trochu jednoduchšie:
O tom jsem take uvažoval, ale připadalo mi to jako prasarna.
V ToolBar mam ikonu, ktera mi take Form 2 vykresli, kdyby se chtěl přihlasit někdo jiny.
Možna by šlo simulovat to kliknuti hned při spouštění.
Ale zatim jsem nezkoušel a obratil se o pomoc u profiku.



Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #21 kdy: 17-03-2013, 09:32:59 »
A to jak zajistim.
Určitě v options ale nemohu najit  :(
No sice neuvadis, co mas za Delphi, ale podle me je to vsude hned na rane: Project | Options | Forms | Auto-Create forms, akorat jednu je to zalozka, jindy vetev ve stromu.

Ale nejjednoduzsi je otevrit si .DPR (v project manageru das na pojektu View Source nebo Ctrl+V) a nechas si tam pouze jeden prikaz z hlavnim oknem.
Kód: Delphi [Vybrat]
  1.   Application.CreateForm(...);
  2.  
Ovsem pokud tam mas formularu vice nez jen hlavni a login, tak budes muset zajistit, aby se ti ve vhodnou dobu vytvarely. Nechavat je v tom .DPR, pokud je aplikace skutecne nepotrebuje po celou dobu, je prasarna.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #22 kdy: 17-03-2013, 09:40:35 »
1) Vytvorím Form1 a Form2.
2) V procedúre OnShow u Form1 spustím obyčajný Timer, ktorý napr. po pol sekunde spustí Form2.
Je to jednodušší v tom, že to uděláš čistě prostředky Delphi a téměř celé v GUI, nemusíš se zabývat programováním nebo dokonce WinAPI. Ale má to i své nevýhody - například je to náročnější na zdroje a hlavně se blbě odhaduje ten časový interval (na hodně pomalém nebo zatíženém počítači ta půlsekunda nemusí stačit, rychlého uživatele zase ta půlsekunda bude zdržovat). Řešení s PostMessage ani jednu z těchto nevýhod nemá.

kk

  • Host
Re:Spuště Form2 s Form1
« Odpověď #23 kdy: 18-03-2013, 06:53:09 »
Tak zas par hodin zkoušení a nic.
Vypada to že Delphi  a ja jsou 2 věci ktere k sobě nepasuji  :'(
Přes ten timer to funguje ale jen s Form2.show.
U Form2.showmodal se vykreslí Form a pak vyskoči hlaška Cannot make a visible window modal

Vice se mi libil ten 2 zpusob od pepka ale netušim kde dělam chybu.

Kód: Delphi [Vybrat]
  1. unit Unit1;
  2. interface
  3.  
  4. uses
  5.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  6.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs,password;
  7.  
  8. const
  9.   WM_USER_POVYTVORENIFORMULARE = WM_USER + 1;
  10. type
  11.   TForm1 = class(TForm)
  12.   private
  13.     procedure WMUserPoVytvoreniFormulare(var Msg: TMessage); message WM_USER_POVYTVORENIFORMULARE;
  14.   public
  15.     constructor Create(AOwner: TComponent); override;
  16.   end;
  17.  
  18. var
  19.   Form1: TForm1;
  20.  
  21. implementation
  22.  
  23. constructor TForm1.Create(AOwner: TComponent);
  24. begin
  25.   inherited Create(AOwner);
  26.   PostMessage(Handle, WM_USER_POVYTVORENIFORMULARE, 0, 0);
  27. end;
  28.  
  29. procedure TForm1.WMUserPoVytvoreniFormulare;
  30. begin
  31.   // Tady uz si delej, co potrebujes
  32.   password1.showmodal;
  33. end;
  34. end.
  35.  
Udělal jsem tak jak radil pf1957.
Zajistil, aby se vytvarel jen hlavni form.
Dopadlo to tak že se nevykresli ani Form1 a vyskoči

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #24 kdy: 18-03-2013, 08:12:39 »
Přes ten timer to funguje ale jen s Form2.show.
U Form2.showmodal se vykreslí Form a pak vyskoči hlaška Cannot make a visible window modal
Musis ten Form2 v design time nastavit jako invisible a po jeho zavreni ho zase skryt (akci v OnClose), abys ho mohl priste znovu zobrazit.

Udělal jsem tak jak radil pf1957.
Zajistil, aby se vytvarel jen hlavni form.
Dopadlo to tak že se nevykresli ani Form1 a vyskoči

No nejspis jsi udelal neco, co jsi nemel... Ale bez tveho kodu tezko vestit, co tam prasis

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1142
  • Karma: 42
    • Verze Delphi: 7, 2010
Re:Spuště Form2 s Form1
« Odpověď #25 kdy: 18-03-2013, 08:28:35 »
Tak zas par hodin zkoušení a nic.
Vypada to že Delphi  a ja jsou 2 věci ktere k sobě nepasuji  :'(
Přes ten timer to funguje ale jen s Form2.show.
U Form2.showmodal se vykreslí Form a pak vyskoči hlaška Cannot make a visible window modal

ono by stacilo prvne vypnout timer a pak volat showmodal :D :D :D
« Poslední změna: 18-03-2013, 11:29:38 od < z > »

kk

  • Host
Re:Spuště Form2 s Form1
« Odpověď #26 kdy: 19-03-2013, 06:20:58 »
Tak už jsem to přes ten timer rozchodil.
Dik moc všem za pomoc.

K.K

  • Host
Re:Spuště Form2 s Form1
« Odpověď #27 kdy: 19-03-2013, 07:50:43 »
Moh bych ještě jeden dotaz lamy.
Když do toho Form2 dam button a na něj přikaz form1.close je vše OK a po kliknuti se cely program ukonči.
Proč to nefunguje ve Form2.FormClose
Když kliknu ve Form 2 na křižek (uzavřit) aby se ukončil i form1.

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1142
  • Karma: 42
    • Verze Delphi: 7, 2010
Re:Spuště Form2 s Form1
« Odpověď #28 kdy: 19-03-2013, 08:25:58 »
aplikace se neobejde bez hlavniho formulare (Form1) - zrusenim zavres celou aplikaci,
aplikace se obejde bez jinych vedlejsich formularu (Form2) - zrusenim zavres jen dany vedlejsi formular ;)

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1493
  • Karma: 37
    • Pepak.net
Re:Spuště Form2 s Form1
« Odpověď #29 kdy: 19-03-2013, 08:54:28 »
aplikace se neobejde bez hlavniho formulare (Form1)
Obejde. Ale musíš si to sám zařídit (v .dpr souboru za Application.Run), Delphi to za tebe neudělají.

k.k

  • Host
Re:Spuště Form2 s Form1
« Odpověď #30 kdy: 19-03-2013, 09:07:39 »
Citace
aplikace se neobejde bez hlavniho formulare (Form1) - zrusenim zavres celou aplikaci,
Toho chci docilit.
Když dem ve Form1 do buttonu form1.close tak zavřu celou aplikaci.
Když to však dam do Form2.FormClose tak ne.

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Spuště Form2 s Form1
« Odpověď #31 kdy: 19-03-2013, 09:25:40 »
Kód: Delphi [Vybrat]
  1. Application.Terminate;
  2.  
Zkus to do eventu OnClose. Mělo by to fungovat. Popř. můžeš i volat Form1.Close, nebo ne?
« Poslední změna: 19-03-2013, 09:28:05 od oxo »
Embarcadero Technology Partner

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2790
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Spuště Form2 s Form1
« Odpověď #32 kdy: 19-03-2013, 09:41:38 »
Moh bych ještě jeden dotaz lamy.
Když do toho Form2 dam button a na něj přikaz form1.close je vše OK a po kliknuti se cely program ukonči.
Proč to nefunguje ve Form2.FormClose
Když kliknu ve Form 2 na křižek (uzavřit) aby se ukončil i form1.
Lama, nelama, ale premyslet bys mohl, ne?
Kdyz si das tlacitko a do jeho udalosti prikaz form1.close, tak tim explicitne rikas, ze chces pri stisku tlacitka zavrit form1. Ale zavreni okna je prece uplne jina udalost a s tvym tlacitkem nema nic spolecneho (napr. existuje, i kdyz tam zadne tlacitko nemas). Takze pokud to chces resit explicitni operaci pro zavreni formu1 (architektonicky je to prasarna, protoze Form1 vytvarel Form2 a Form2 by nemel o existenci Form1 nic nevedet, protoze ho mohl klidne vytvorit treba  form150 apod., pokud uz si ty formulare tak hloupe pojmenovavas), tak tu operaci budes muset predepsat pri zavreni okna jeste jednou.