Toon posts:

[Delphi] MDI Child afsluiten

Pagina: 1
Acties:

Verwijderd

Topicstarter
De volgende situatie doet zich voor:

Ik klik op het kruisje van de MDI parent (hoofdformulier). Hierdoor wordt de formclosequery van het MDI Child aangeroepen. Hierin wordt de gebruiker gevraagd of hij/zij de bewerkingen in dat child wil beeinidigen of niet. Daarna wordt gevraagd of de gebruiker het hele gehele programma wil afsluiten (dmv de formclosequery op het hoofdformulier).

Als ik in deze situatie ervoor kies om het MDI child te sluiten en vervolgens er alsnog voor kies om het programma niet te sluiten, dan wordt het MDI Child ook niet gesloten terwijl ik hiervoor wel een bevestiging heb gegeven. Debuggen leverde op dat wel de formclosequery van het MDI child wordt aangeroepen maar daarna merkwaardig genoeg niet de formclose.

Dit brengt een aantal praktische bezwaren met zich mee. Bijvoorbeeld: Op het MDI child worden databewerkingen gedaan icm een database. De queries die hiervoor gebruikt worden, worden bij een 'annuleer' actie afgebroken en gesloten. Dit hangt aan de formclosequery. Vervolgens moet dan ook het formulier gesloten worden anders kunnen er operaties worden uitgevoerd op queries die niet actief zijn. Dit werkt prima wanneer ik op het kruisje van het MDI child zelf klik, maar niet wanneer ik op het kruisje van de MDI parent klik, want dan wordt dus in de bovenstaande situatie de onclose van het MDI Child niet uitgevoerd.

Wie kan mij vertellen hoe ik de onclose event wel kan laten uitvoeren ipv dat alleen de formclosequery worden aangeroepen of heeft wellicht een andere oplossing?

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:40
code:
1
action := caClose


Vind je terug in de help van Delphi/VCL over MDI forms sluiten.

https://fgheysels.github.io/


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Delphi:
1
Action := caFree;


Zorgt er voor dat het form ook meteen vrijgegeven wordt.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
code:
1
Action := caFree;

Dit staat ook wel in de onclose van de MDI childs, maar de onclose event wordt simpelweg niet aangesproken in bovenstaande situatie. In de help van Delphi staat bij mijn weten ook wel dat het sluiten van de MDI parent er niet voorzorgt dat de onclose event van het MDI child wordt uitgevoerd.

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Laat eens wat code zien dan, want het lijkt er sterk op dat je ergens nog wacht op een antwoord van de gebruiker, terwijl hem geen vraag gesteld wordt. Is het toevallig niet zo dat je alleen sluit als beide close-vragen positief beantwoord worden?

Als je de results in variabelen zet en een van die variabelen wordt niet veranderd omdat de vraag niet gesteld wordt, dan zou het kunnen dat de MDI niet afgesloten wordt?

Hoe dan ook, code helpt. Relevante code that is ;)

My personal website


Verwijderd

Wat doe je nu precies?
Hierin wordt de gebruiker gevraagd of hij/zij de bewerkingen in dat child wil beeinidigen of niet. Daarna wordt gevraagd of de gebruiker het hele gehele programma wil afsluiten (dmv de formclosequery op het hoofdformulier).
Hoe ziet je canclose van het mdi child eruit dan? Doe je daarin een application.terminate, welke je in de canclose van het hoofdform cancelled?

Verwijderd

Topicstarter
OZ-Gump schreef op woensdag 16 maart 2005 @ 13:33:
Laat eens wat code zien dan, want het lijkt er sterk op dat je ergens nog wacht op een antwoord van de gebruiker, terwijl hem geen vraag gesteld wordt. Is het toevallig niet zo dat je alleen sluit als beide close-vragen positief beantwoord worden?
Dan sluit het programma ook wel af. Het is echter zo dat er een formclosequery aan het MDI child hangt en aan de MDI parent. Wanneer je dus de de formclosequery van de MDI parent aanroept, roept deze automatisch eerst de formclosequery aan zijn kinderen (MDI Childs). Je krijgt hierdoor dus ook 2 vragen; de eerst vraag of je de bewerkingen op het child wilt beeinidigen en daarna of je het hele programma wilt sluiten. Wanneer ik dan de eerst vraag bevestig (zit dus in de formclosequery van het MDI Child) en daarna de tweede vraag afwijs (dus of ik het hele programma wil sluiten - formclosequery van de parent), zal het programma wel blijven draaien (logisch, want geen bevestiging gegeven), maar het child form blijft geopend (onlogisch, want juist bij formclosequery opgegeven dat ie kon sluiten). Het komt er dus opneer dat de onclose event van het MDI child niet wordt aangeroepen na de formclosequery. Ik wil het zo hebben dat ie de onclose van het MDI child juist WEL uitvoert.
Hoe dan ook, code helpt. Relevante code that is ;)
Code volgt zsm...

Verwijderd

Ik heb je probleem even heel envoudig nagebootst. Twee forms, een MDIForm (Form1) en een MDIChild (Form2).

Het MDIForm heeft een onclosequery:
Delphi:
1
2
3
4
5
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin

  Canclose:= MessageDlg('weet u zeker dat u de applicatie wilt sluiten?',mtconfirmation,[mbOk, mbCancel],0)=mrOk;
end;


Het MDI Child heeft een onclosequery en een onclose:
Delphi:
1
2
3
4
5
6
7
8
9
procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Canclose:= MessageDlg('weet u zeker dat u dit formulier wilt sluiten?',mtconfirmation,[mbOk, mbCancel],0)=mrOk;
end;

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


Deze applicatie vertoont precies de kuren waar jij het over hebt.

Je ziet ook dat nadat je op 'yes' hebt geklikt bij de 1e vraag ('weet u zeker of u dit formulier wilt sluiten'), dat dit formulier niet gesloten wordt. Het lijkt er op dat hij eerst alle closequeries afwerkt, alvorens tot de daadwerkelijke close over te gaan.

De enige oplossing lijkt mij dan ook om in de canclose van het hoofdformulier zelf het child vrij te geven.

Verwijderd

Topicstarter
Verwijderd schreef op woensdag 16 maart 2005 @ 17:51:
De enige oplossing lijkt mij dan ook om in de canclose van het hoofdformulier zelf het child vrij te geven.
Dat klinkt opzich goed, maar wat als ik als gebruiker ervoor kies om het MDI Child niet te sluiten (bijv. omdat ik toch wil afmaken waarmee ik bezig was). Het MDI Child zal dan volgens mij altijd gesloten worden en dat is niet de bedoeling. Het formulier moet alleen gesloten worden als de gebruiker daartoe een bevestiging geeft. Kortom: Het is niet fout-proof.

Een tweede optie is om de de cancel vraag van het MDI child te onderdrukken in het geval dat de applicatie in zijn geheel gesloten wordt. Je houdt dan maar een bevestiging van de gebruiker over, namelijk 'Wil u het programma echt verlaten?'. Indien er ja geklikt wordt worden alle formulieren incl het hoofdformulier gesloten en als er nee geklikt wordt gebeurd er ook helemaal niets met het MDI Child. Ik zou alleen niet zo weten hoe ik dit elegant kan programmeren met behoud van de annuleer bevestiging voor het sluiten van het child als ik op het kruisje van het child zelf klik.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Als ik me niet vergis is op zo'n moment Application.Terminated True.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Nope..

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Zelf een vlaggetje maken dan?

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Idd, zoiets zal het wel worden dan. Of de hele closequery van het childform laten vallen, en dat door het MDI form laten uitvoeren. Of andersom, de closequery van het main form laten vallen en zelf iets soortgelijks maken.

Verwijderd

Topicstarter
Pfff, toch raar dat niet eleganter kan. Je zou toch zeggen dat heel veel mensen met de geschetste situatie te maken krijgen

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 10-05 14:05

Robtimus

me Robtimus no like you

Ik zou hoe dan ook het afbreken en sluiten van de queries in de formclose van de MDI children doen. Je wilt het nml doen wanneer ze zeker weten worden afgesloten, en daar ben je op dat punt het meest zeker van.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Ok, Ik heb het nu als volgt kunnen oplossen:

De functionaliteit voor het afsluiten van een MDI Child volledig onder gebracht in de formclose van het MDI Child (zoals IceManX zei). Verder heb ik een Super form aangemaakt waarvan alle MDI Childs erven. In dit Super form zit een een virtual CleanUp procedure, zodat elk MDI Child zijn eigen implementatie van CleanUp heeft. Het is nu mogelijk om vanuit de MDI parent (wanneer ik op kruisje klik) de cleanup instantie van alle MDI Childs aan te roepen.
code:
1
TSuperForm(MdiChildren[i]).CleanUp;

Graag zou ik jullie mening horen of deze oplossing netjes is. Functioneel werk het verder prima.
Pagina: 1