Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Da li je MDIChild forma kreirana ?

[es] :: Pascal / Delphi / Kylix :: Da li je MDIChild forma kreirana ?

Strane: 1 2

[ Pregleda: 4545 | Odgovora: 20 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Da li je MDIChild forma kreirana ?18.02.2010. u 11:17 - pre 171 meseci
Kreirao sam formu koju koristim kao template, sa ugrađenim procedurama koje mi se vrte na svakoj formi. Od te forme nasljeđujem forme koje u stvari koristim u programu.

Forme kreiran pri pozivu, dakle u run-time.

Problem je sljedeći: kako u main formi, na kojoj kreiran child forme znati da li je forma kreirana ili ne?
Probao sam sa Assgned, nil.

Ne radi ako na child formi ne kažem u proceduri OnClose -> fmFormChild1:= nil

Kako to reći u template formi od koje nasljeđujem forme tako da to ne moram raditi na svakoj koju koristim?
Probao sam sa self := nil, ne prolazi.

Kako znati da li je forma kreirana ili ne?
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
*.dynamic.isp.telekom.rs.



+62 Profil

icon Re: Da li je MDIChild forma kreirana ?18.02.2010. u 14:22 - pre 171 meseci
Pitanje ti nije najjasnije.

Da li zelis da osiguras da bude max po jedna instanca od svakog nasledjenog form-a kreirana? Ako da, kod je prost:

Code:


function TMainForm.GetChildForm(MyChildFormClass: TFormClass): TForm;
var
  i: integer;

begin
  result := nil;
  i := 0;
  while (i < MDIChildCount) and not(MDIChildren[i] is MyChildFormClass) do
    inc(i);
  if i < MainForm.MDIChildCount then
    result := MDIChildren[i];
end;


Medjutim, ako se kreira vise od jedne instance svake nasledjene klase, stvar se prilicno komplikuje; zavisi kako se kreiraju. Kako god, gornji kod radi i u tom slucaju.

Pozz

Rajko

P.S. Napomena: za one koji se dosad nisu susretali sa metaklasama, deklaracija TFormClass je predefinisan tip, i bukvalno ide ovako

Code:

  TFormClass = class of TForm;

 
Odgovor na temu

priki

Član broj: 24732
Poruke: 700
*.datalab.si.

ICQ: 174153511


+26 Profil

icon Re: Da li je MDIChild forma kreirana ?18.02.2010. u 14:56 - pre 171 meseci
Na tvom mestu bih napravio jednu klasu, recimo FormsManager
koja bi sadrzala funkcije za kreiranje, maipulisanje (traženje, provera jel forma kreirana) formi u programu....

U tom forms manager-u jedna TObjectList bi bila glavna stvar gde bih držao kreirane forme i sve radio preko nje
takodje i oslobadjao memoriju na kraju
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?18.02.2010. u 19:56 - pre 171 meseci
Izgleda da nisam najbolje objasnio.

U main formi kreiram sve ostale forme, ovisno što korisnik radi.
Isto tako korisni može zatovriti neku od tih formi.

1. Kada korisnik pritisne npr. gumb - "Unos stavke" kreira se forma fmUnos
2. Nakon što korisnik unese što želi - zatvori formu.

E, sad, što ako pritisne gumb "Unos stavke" dok još nije zatvorio formu ili ako zatvara main formu, a još postoje druge aktivne forme? Kako da znam da je forma kreirana ili ne? Mogao bih uvesti varijablu koja bi se setirala pri kreiranju forme... Najljepše rješenje bi bilo kada bih mogao direktno detektirati da li je neka forma kreirana.

Sad koristim metodu:
u main formi, tamo gdje kreiram formu imam kod:
Code:

if NekaForma <> nil then NekaForma := tNekaForma.Create(nil);
NekaForma.BringToFront;


Ono što želim izbjeći je u toj NekojFormi, u OnClose imam:
Code:

FreeAndNil(NekaForma);

bez toga ne radi dio u main formi, ondosno, radi samo prvi put..

u OnClose main forme imam:
Code:

if NekaForma <> nil then NekaForma.Close;
...


 
Odgovor na temu

gpedja_70
programer
Novi Sad, Srbija

Član broj: 224317
Poruke: 53
*.wobyhaus.co.rs.



+2 Profil

icon Re: Da li je MDIChild forma kreirana ?19.02.2010. u 10:53 - pre 171 meseci
Mogao bi da stavis u OnClose

Code:
Action := caFree;


ali ti to ne garantuje da ce NekaForma biti nil

Mada mislim da ti u ovom slucaju nece ni trebati provera
Code:
if NekaForma <> nil then NekaForma := tNekaForma.Create(nil);

nego ces svaki put morati kreirati NekaForma-u ...


pozz
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?19.02.2010. u 12:12 - pre 171 meseci
Nije problem free-anje forme. To se odradi.
Probao sam staviti Action = caFree, ne pomaže.

Problem je u glavnoj formi znati da li je NekaForma kreirana ili ne.

Korisnik može bilo kada britisnuti gumb za prikaz npr. artikala što mora prikazati formu fmArtikli.
Nakon što ju prikazao formu, korisnik ju može zatvoriti, ali i ne mora. Bilo da ju zatvori ili ne, nakon prvog kreiranja u glavnoj formi će uvijek biti fmArtikl <> nil
Nakon ponovnog pristiska na gumb za prikaz artikala, forma fmArtikli se mora prikazati. Ako je zatvorene - najprije kreirati, a ako nije - samo prikazati.

Tu metodu koristim u večini programa i zato bi mi dobro došla metoda otkrivanja da li je forma kreirana.
Sada sam uveo način da ne kreiran forme kao nasljednike TForm već kriram tem. formu, a sve ostale kreiram iz nje. Na taj način mogu hrpu poslova koje radim na OnShow, OnCreate ili OnClose - staviti u tu temp. formu.
 
Odgovor na temu

gpedja_70
programer
Novi Sad, Srbija

Član broj: 224317
Poruke: 53
*.wobyhaus.co.rs.



+2 Profil

icon Re: Da li je MDIChild forma kreirana ?19.02.2010. u 14:09 - pre 171 meseci
zar to nije ono sto ti je Rajko napisao?
 
Odgovor na temu

Oziris
BiH

Član broj: 12887
Poruke: 13
89.146.185.*



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?22.02.2010. u 07:04 - pre 171 meseci
Koliko sam uspio shvatiti, zelis da se prilikom zatvaranja tvoje izvedene child forme referenca na tu formu automatski postavi na nil, a da pri tome dio koda koji to odradjuje ne moras svaki puta dodavati u OnClose event svake child fome nego da se nalazi u template formi?

Sustina je da na neki nacin trebas u template formi doci do vrijednosti varijable koja referencira tvoju child formu i njom manipulsati u template formi.

Rjesenje koje meni trenutno pada na pamet za template formu je sljedece (minimum koda za template formu):

Code:

unit Temp;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, AdvPanel, ExtCtrls;

{Tip podatka koji ce predstavljati pokazivac na varijablu koja referencira tvoju child formu}
type
   PTForm = ^TForm;

type
  {Deklaracija tvoje template forme}
  TfrmTemp = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    FRef: PTForm; //Koristiti ce kao pokazivac na nama zeljenu referencirajucu varijablu
  public
    { Public declarations }
    {Overload konstruktora, preko ovog konstruktora ces kreirati svaku svoju child formu}
    constructor Create (AOwner: TComponent; mForma: PTForm); reintroduce; overload;
  end;

var
  frmTemp: TfrmTemp;

implementation

{$R *.dfm}

constructor TfrmTemp.Create(AOwner: TComponent; mForma: PTForm);
begin
   inherited Create(AOwner);
   FRef := mForma; //Cuvamo adresu referencirajuce varijable
end;

procedure TfrmTemp.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   Action := caFree;
   FRef^ := Nil; //Na kraju toj referencirajucoj varijabli dodjeljujemo vrijednost Nil
end;

end.


U Main formi kreiras child forme na sljedeci nacin:

Code:

procedure TfrmMain.Button1Click(Sender: TObject);
begin
   if not Assigned(frmIzvedena) then
      frmIzvedena := TfrmIzvedena.Create(Application,@frmIzvedena);
   frmIzvedena.Show;
end;


Nadam se da sam te dobro shvatio sta zelis i da ce ti biti od pomoci. Pozdrav.
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?22.02.2010. u 14:21 - pre 171 meseci
Hvala Oziris, to me je zanimalo. Rješenje je jednostavno, shvatio sam prije nego sam pogledao kod.

Ovo mi je potaklo sljedeće pitanje:

Kako, općenito, znati da li je neki objekt kreiran ili ne?

Vrijednost varijable tipa tNekaKlasa je nill do trenutka prvog kreiranja objekata. Nakon toga, bez obzira na free vrijednost je različita od nill.
Ako se pokuša koristiti s objektom nad kojim je napravljen free, program javi grešku.
Kako znati da li taj objekt postoji ili ne?
 
Odgovor na temu

priki

Član broj: 24732
Poruke: 700
*.dynamic.dsl.t-2.net.

ICQ: 174153511


+26 Profil

icon Re: Da li je MDIChild forma kreirana ?22.02.2010. u 16:13 - pre 171 meseci
ovo resenje te ogranicava da za svaku formu moras imati kreiranu promenjivu...
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?22.02.2010. u 21:52 - pre 171 meseci
priki, ne.

varijabla FRef se definira samo u temp formi od koje nasljeđujem ostale forme. Samo se tamo deklarira i snjom se barata.
frmIzvedena je ime kreirane forme, koristi se u main formi gdje kreiram ili dovodim u "front" određenu formu, a ona je tako i tako kreirana. Izmjena je jedino u načinu kreiranja objekta, tj. pozivu konstruktora s jednim pozivim više.

Nego, nitko mi ne odgovori na sljedeće pitanje:
Kako, općenito, znati da li je neki objekt kreiran ili ne? Svejedno od koje klase.
 
Odgovor na temu

priki

Član broj: 24732
Poruke: 700
*.datalab.si.

ICQ: 174153511


+26 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 06:57 - pre 171 meseci
a šta ako ti se javi potreba da imaš više tih frm formi odjednom :-)

samo pokušavam da ti kažem da sagledaš stvari na više objektan način
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 08:02 - pre 171 meseci
Za ono za što mi treba, uvjek je samo, jednog tipa, jedna forma kreirana. Može biti više MDIChild formi, ali sam jedna jednog tipa (fmArtikli, fmUlaz...). Korisni može zatovriti aktivnu formu ili otvoriti novu, a trenutno aktivnu ostaviti. Kod kreiranja forme radim hrpu stvari: otvaranja dataset-ova, inicijalizacija varijabli... ako je forma ostavljena, nije zatvorena, prelazak na nju je puno brži.
Ako sva otvaranja dataset-ova radim kod starta programa - programu treba puno više vremena da se pokrene, a neke od dataset-ova korisnik neće niti koristiti...

Korištenje template forme od koje nasljeđujem sve forme mi se pokazalo prilično korisnim (na isti način radim i reporte - qickreport). Sve logo-e firme postavljam na tu formu. U OnKeyPress stavljam kod koji ENTER pretvara u TAB itd.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
*.dynamic.isp.telekom.rs.



+62 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 12:03 - pre 171 meseci
U gornjem kodu (resenje sa pointerom na formu), postoji jedna opasnost, a to je da referenca FRef^ u medjuvremenu postane nevalidna (neispravan pointer).
Znaci, nikako ne koristiti lokalne varijable prilikom kreiranja child formi, odnosno, ako su u pitanju globalne varijable (na glavnoj formi), nikako ne ubijati glavnu formu.

Rajko
 
Odgovor na temu

tkaranovic
Tomislav Karanović
Beograd

Član broj: 220507
Poruke: 307



+18 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 15:52 - pre 171 meseci

[Ovu poruku je menjao tkaranovic dana 23.02.2010. u 17:20 GMT+1]



[Ovu poruku je menjao tkaranovic dana 23.02.2010. u 17:22 GMT+1]

[Ovu poruku je menjao tkaranovic dana 23.02.2010. u 17:22 GMT+1]
 
Odgovor na temu

tkaranovic
Tomislav Karanović
Beograd

Član broj: 220507
Poruke: 307



+18 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 16:26 - pre 171 meseci
Prethodni poruku sam napisao a da nisam pažljivo pročitao prethodne...

Što bi rekli offtopic:
Onda sam pokušavao da ustanovim kako radi brisanje i(li) prepravka poruka... Tek iz trećeg puta sam uspeo da obrišem sadržaj a brisanje cele poruke izgleda i nije moguće... :)
 
Odgovor na temu

Oziris
BiH

Član broj: 12887
Poruke: 13
*.team.ba.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?23.02.2010. u 20:42 - pre 171 meseci
Citat:
franjo_tahi:

Kako, općenito, znati da li je neki objekt kreiran ili ne?



Bojim se da ne postoji elegantno rjesenje ovoga, osim dodjeljivanja nil vrijednosti varijabli koja referencira objekat prilikom unistavanja objekta. Objekat licno nije u mogucnosi da zna koje se sve varijable referenciraju na njega, tako da ne moze njima ni manipulisati prilikom svog unistenja. To 'neznanje' smo u prethodnom primjeru pokusali 'zaobici' prosljedjivanjem adrese varijable koja treba da referencira taj objekat, tako da bi mogli manipulisati vrijednoscu varijable prilikom unistenja tog objekta. Naravno da ovo nije ni elegantno ni idealno rjesenje, ali je mozda zadovoljilo tvoju potrebu posto si htio taj dio koda dodjeljivanja nil vrijednosti drzati u Temp formi. Problem bi se recimo javio kada bi imao dvije varijable koje referenciraju na jednu te istu instancu objekta (ne na dvije razlicite instance). Tada bi pri unistenju objekta nil vrijednost bila dodjeljenja jednoj varijabli dok bi druga varijabla ostala neispravna referenca, ali to tebi ni ne treba.

Citat:
priki

a šta ako ti se javi potreba da imaš više tih frm formi odjednom :-)



Sa ovim mislis, vise kreiranih instanci jedne te iste forme odjednom? Izuzimajuci cinjenicu da to nije ono sto je Franjo trazio, to mu je sasvim moguce ukoliko ne bude prosljedjivao drugi parametar kontstruktoru (naravno uz neke dorade prikazanog koda, recimo zbog exception-a ukoliko bi FRef bila jednaka nil). Ukoliko zeli da kontrolise da li je bas 'taj' objekat jedne te iste klase vec kreiran, morace da koristi vise globalnih varijabli i proslijedi ih konstruktoru.

Citat:
Rapaic Rajko

U gornjem kodu (resenje sa pointerom na formu), postoji jedna opasnost, a to je da referenca FRef^ u medjuvremenu postane nevalidna (neispravan pointer).



Moze li objasnjenje sta bi se desilo ukoliko FRef^ postane nevalidna referenca?
 
Odgovor na temu

tkaranovic
Tomislav Karanović
Beograd

Član broj: 220507
Poruke: 307



+18 Profil

icon Re: Da li je MDIChild forma kreirana ?25.02.2010. u 04:35 - pre 171 meseci
Citat:
franjo_tahi:

Kako, općenito, znati da li je neki objekt kreiran ili ne?

Vrijednost varijable tipa tNekaKlasa je nill do trenutka prvog kreiranja objekata. Nakon toga, bez obzira na free vrijednost je različita od nill.
Ako se pokuša koristiti s objektom nad kojim je napravljen free, program javi grešku.
Kako znati da li taj objekt postoji ili ne?

Ako se posmatra kao objekat ne postoji drugi način osim Assigned, a tako može jedino ako se posle free koristiti nil.

Ako se uzme u obzir da je objekat još nešto konkretno, onda se može proveravati po nekoj drugoj karakteristici i pronaći drugačiji način da se proveri da li postoji. Pošto je konkretno objekat MDIChild i ako se to uzme u obzir onda (ako se preskaču MDIForm funkcije) može se proveriti ovako:

Direktno se proverava da li MDIChild kreirana. AssignedMDIChild je funkcija koja je za MDI potomke, bili oni izvedeni iz neke zajedničke MDIChild forme ili ne:

Code (delphi):

function AssignedMDIChild(MDIFormHandle: hwnd; MDIChildClass: PChar): boolean;
  var MDIClientHwnd, Childhvnd: hwnd;
begin
  MDIClientHwnd := FindWindowEx(MDIFormHandle, 0, 'MDIClient', nil);
  if MDIClientHwnd = 0 then
   raise Exception.Create('Greska ne postoji main MDIforma');
  Childhvnd := FindWindowEx(MDIClientHwnd, 0, MDIChildClass, nil);
  result := Childhvnd <> 0;
end;
...

  if AssignedMDIChild(MainMDIForm.Handle, 'TMDIChild') then //TMDIChild ili TMDIChildIzvedena...
   showmessage('ima')
  else
   showmessage('nema');
 
 
Odgovor na temu

franjo_tahi
Franjo Tahi
Zagreb

Član broj: 34712
Poruke: 399
*.adsl.net.t-com.hr.



+1 Profil

icon Re: Da li je MDIChild forma kreirana ?25.02.2010. u 13:12 - pre 171 meseci
Zahvaljujem svima na pomoći.

Iskušao sam kod koji je postavio tkaranovic, radi dobro i njega ću iskoristiti.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
*.dynamic.sbb.rs.



+62 Profil

icon Re: Da li je MDIChild forma kreirana ?25.02.2010. u 20:41 - pre 171 meseci
Citat:
Oziris: Moze li objasnjenje sta bi se desilo ukoliko FRef^ postane nevalidna referenca?


Evo primera, upravo iz tvog koda, koristicemo lokalnu varijablu umesto "globalne"

Code:

procedure TfrmMain.Button1Click(Sender: TObject);
var
  afrmIzvedena: TfrmIzvedena;
begin
  // if not Assigned(frmIzvedena) then
    afrmIzvedena := TfrmIzvedena.Create(Application, @afrmIzvedena);
  afrmIzvedena.Show;
end;


U gornjem kodu je upotrebljena lokalna varijabla (na steku). Cim se izadje iz procedure, stek se brise, tako da sad u afrmIzvedena imamo neispravan pointer/referencu na sebe samu.
Recimo da smo izvrsili gornji kod, kreirali formu afrmIzvedena, i zatim istu zatvorili (Close). Prividno, sve je u redu...ali zapravo nije :) .

Dokaz. Dopunimo event TfrmIzvedena.FormClose() jednom linijom, i zatim pokusajmo ponovo:

Code:

procedure TfrmIzvedena.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  ShowMessage(FRef^.ClassName); // ovo radi samo ako je referenca validna, inace...
  FRef^ := nil;
end;


Gornji kod/event pokusati i sa prvim slucajem, kad se koristi/kreira globalna referenca frmIzvedena... i, to je to.

Pozz

Rajko


[Ovu poruku je menjao Rapaic Rajko dana 25.02.2010. u 21:56 GMT+1]

[Ovu poruku je menjao Rapaic Rajko dana 25.02.2010. u 21:57 GMT+1]
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Da li je MDIChild forma kreirana ?

Strane: 1 2

[ Pregleda: 4545 | Odgovora: 20 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.