Results 1 to 4 of 4

Thread: Form oproepen met als parameter self

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747

    Form oproepen met als parameter self

    Situatie:

    Een form wordt opgestart. In die form wordt er op een button gedrukt, die een ander scherm opstart.
    Delphi Code:
    1. callform(self);
    De procedure ziet er als volgt uit:
    Delphi Code:
    1. procedure callform(form : Tform);
    2. var f : TForm2;
    3. begin
    4.   f := TForm2.create(form);
    5.   f.showmodal;
    6. end;
    Form2 wordt gestart en weer afgesloten.
    Form2 wordt weer gestart en weer afgesloten.
    Form2 wordt weer gestart en weer afgesloten.
    De form, waar de functie staat, wordt afgesloten.

    Omdat Tform2 de ansestor heeft van de form, wordt form2 ook vrijgegeven. Maar dat is alleen voor de laatste oproep.
    Die andere twee zijn dan toch niet vrij gegeven waardoor een memoryleak ontstaat?
    Delphi is great. Lazarus is more powerfull

  2. #2
    Ja hoor. Al die TForm2 instances hebben die eerste als owner. Die owner heeft dus een hele lijst verwijzingen en zal ze allemaal vrijgeven.

    Maar het is handiger om ze allemaal vrij te geven zodra dat kan.

    Dat kan binnen callform. ShowModal blijft wachten tot het form gesloten is, dus daarna kan je F.Free aanroepen.
    Je kan ook caFree in het FormClose event van Form2 zetten. Dat is vooral handig voor forms die niet modal zijn.
    1+1=b

  3. #3
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Oke. Dan is Delphi toch iets intelligenter dan ik had verwacht.

    Mijn instelling zal ook zijn dat je iets vrij geeft als je het niet meer gebruik, maar kennelijk denken ze hier toch iets anders.
    Delphi is great. Lazarus is more powerfull

  4. #4
    Een TComponent is een beetje als een farao. Hij neemt alles wat ie heeft mee het graf in.

    Je maakt het aanroepende form eigenaar van de form2 instantie door 'Self' mee te geven als owner. Dat zorgt er achter de schermen voor dat de instantie in het lijstje met `Components` van het form staat. De form2 instantie heeft maar 1 owner (of nil, voor een vogelvrije), maar elk component kan wel eigenaar zijn van meerdere components.

    En dat is dagelijkse kost in Delphi.

    Controls: Parent/Child
    Dit is geërfd van TControl en TWinControl.
    Een via de designer opgebouwd form kan een flinke stamboom hebben. Het form bevat een groupbox. Die bevat twee panels, en het eerste panel bevat een button en 3 edits. De edits hebben het panel als parent. Het panel de groupbox, en de parent van de groupbox is het form. Dat is een hiërarchie waar het form uiteindelijk de meest bovenliggende parent is. Alleen TWinControl-afgeleiden kunnen andere controls bevatten. Dus een TForm, TPanel en TGroupbox kunnen andere controls bevatten. Een TButton theoretisch ook, al is die functionaliteit niet zichtbaar in de designer. Via code kan je het wel truken. Een TControl dat geen TWinControl is kan wel op een parent staan, maar zelf niet bevatten. Bijvoorbeeld een TLabel en TImage.
    Via de property Controls kan je alle control (afgeleiden van TControl) vinden waar je control de parent van is.

    Dit is alleen een visuele hiërarchie. Het panel is niet de eigenaar van de button!

    Ownership: Owner/Component
    Maar qua ownership is het rechtlijniger. Al die componenten hebben het form als owner. Als je over de Components lijst van een form (of ander TComponent) loopt, dan krijg je alle TComponent-afgeleiden waar het component eigenaar van is. Voor zo'n form is normaal gesproken het form zelf de eigenaar van alles erop, dus de groupbox, de button, en eventuele niet-zichtbare components, zoals een TImageList of TOpenDialog.

    En dat is ook de situatie waarin je die ownership eigenlijk altijd gebruikt. Je geeft het form vrij, en gaat er dan blind van uit dat al die components ook vrijgegeven worden. Dat gebeurt ook, en het is die ownership die ervoor zorgt.

    Een form kan zelf ook een owner hebben. Een zgn auto-create form (wat in de praktijk gemaakt wordt in de dpr, via Application.CreateForm) krijg Application als owner. Als je applicatie afsluit wordt het TApplication component vrijgegeven en die neemt al z'n forms mee het graf in.

    Heel handig, maar bij grotere en complexere applicaties wil je meestal zelf bepalen wanneer een form wordt gemaakt en vrijgegeven, omdat jij efficient met geheugen om wilt gaan. Al die instanties nemen geheugenruimte in en kosten tijd om te intiializereren bij het opstarten. Bovendien wil je soms meerdere instanties van hetzelfde form. Auto-create werkt dan niet meer, en je gaat aan de slag met code zoals in de vraag gebruikt is.

    En dan is het dus ook handig om zelf het form vrij te geven zodra het niet meer nodig is. Als je een component, zoals een form (want TForm is dus ook afgeleid van TCompontent), zelf vrijgeeft, dan zal hij een bericht sturen naar z'n owner, als die niet nil is. De owner weet dan dat dat component al vrijgegeven is, en zal 'm verwijderen uit z'n lijst met components.

    En daar komt ook de discussie vandaan (laatst weer hier op NLDelphi) of je een owner mee moet geven aan een form dat je toont met ShowModal en daarna direct weer vrijgeeft. Het heeft namelijk weinig zin om dat te doen, dus meestal het is verspilde overhead. Maar het is tegelijk ook maar weinig overhead en kan ook geen kwaad, dus niet het eind van de wereld als het toch gebeurt.
    1+1=b

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •