Formulare ganz löschen



  • hi, ich hab mal eine eigentlich ganz simple klingende Frage(ist es wahrscheinlich auch aber naja 😛 ):

    void __fastcall TForm1::Allgemein1Click(TObject *Sender)
    {
       TTiereigenschaften* new_window = new TTiereigenschaften(this);
       new_window->nummer->Caption = tiere[akt_nummer].nummer;
       new_window->gruppe->Caption = tiere[akt_nummer].gruppe;
      // usw
     ////  new_window->Parent = this; // toll wenn ich Form1 schliesse wird neue Form zerstört... da können aber schon 100000 auf sein ausserdem dreht miene Form dann durch
    
       new_window->Show();
       new_window->BringToFront();
    }
    

    Und zwar hab ich 1000 Buttons, bei Klick auf diese wird automatisch ein Formular erzeugt und angezeigt wie oben im Code.

    Jetzt würde ich gerne das beim Schliessen dieses automatisch erzeugten Formulars(Kreuzchen klicken usw) es auch im RAM gelöscht wird da ich es nicht mehr brauche und ansonsten bei Bedarf neu erzeuge.
    Sonst spielt mein RAM da irgendwann verrückt und das nur weil noch Formulare auf sind die keiner mehr braucht.

    Das sollte ja eigentlich mit delete gehen, aber wo soll ich das hinschreiben? Ins OnClose Ereignis der Form ein "delete this" funktioniert ja nicht.

    [ Dieser Beitrag wurde am 12.03.2003 um 11:16 Uhr von dreaddy editiert. ]



  • Ist es eine MDI, erzeugst du Child-Window? Dann regelt die MDI das Abräumen. Das wär bei der großen Anzahl sicher auch das beste. Mußt nur eine Form kreieren, ggf. für jeden Childtyp eine.

    new_window->BringToFront();

    macht mich stutzig. Ein neu erstelltes Fenster wird an oberster Position plaziert. Warum ist die Zeile nötig?



  • Ist kein MDI, stell dir das etwa wie den Windows Desktop vor, es sind diverse Symbole auf dem "Desktop" und wenn man die anklickt geht ein neues Fenster auf mit dem Inhalt.

    Das neue Formular soll aber nicht nur in der Form ansich sichtbar sein, daher kein MDI.

    In der Regel hat man auch nur 1-3 dieser Fenster auf, aber wenn man sich die durchschaut macht man halt mal ein Fenster auf, wieder dicht, neues auf usw.. und jedesmal 20 kb mehr RAM Verbrauch ist tödlich auf Dauer.

    Und das BringToFront ist da überflüssig stimmt hatte historische Gründe und ist jetzt aus der Geschichte ausradiert.

    Und das mit dem Parent geht garnicht, habich auchmal rauseditiert, da dreht das neue Formular völlig anner Welle.

    [ Dieser Beitrag wurde am 12.03.2003 um 11:18 Uhr von dreaddy editiert. ]



  • aus dem RAM löschen: einfach delete...



  • Ach wirklich? Und WO soll ich das machen?
    Wenn ich das in einem Ereignis des neu erzeugen Formulars mache hagelts Exeptions und ansonsten wäre nur ein Timer oder so möglich. was allerdings nicht so toll ist.

    [ Dieser Beitrag wurde am 12.03.2003 um 11:23 Uhr von dreaddy editiert. ]



  • Hatte ich mir auch in etwa so vorgestellt, @dreaddy. Ich würde in so einem Fall die Hauptanwendung maximiert starten und Verkleinern gar nicht zulassen. Ist allein schon wegen der Übersicht (normalerweise) das beste.

    Die App kann wie ein ListView aufgebaut sein, ohne Leisten. Dann gibt's keine Beschränkung für die Plazierung der Fenster.

    Ansonsten müßtest du die Fenster in einer Schleife deleten. Das wäre auch praktisch, um zwischendurch mal wieder Luft schaffen zu können, via Button oder Tastakombi die Massenexekution :p befehlen.

    Um sicherzugehen, daß kein gelöschtes Fenster noch mal gelöscht wird

    delete myWindow;
    myWindow = NULL;



  • hm das hatte ich befürchtet, ich hab das jetzt so gemacht

    std::vector<TTiereigenschaften*>tierfenster;
    
    void __fastcall TForm1::Timer1Timer(TObject *Sender) // 30 sek timer
    {
      for(int i = 0; i < tierfenster.size();i++)
      {
        if(tierfenster[i]->killmepls)
        {
          delete tierfenster[i];
          tierfenster.erase(tierfenster.begin()+i);
        }
      }
    }
    
    void __fastcall TForm1::Allgemein1Click(TObject *Sender)
    {
       TTiereigenschaften* new_window = new TTiereigenschaften(this);
       new_window->nummer->Caption = tiere[akt_nummer].nummer;
       new_window->gruppe->Caption = (int)(tiere[akt_nummer].gruppe);
       new_window->Show();
       tierfenster.push_back(new_window);
    }
    

    und im OnClose der neuen Form killmepls = true

    so richtig gefallen tut mir das zwar net(dazu der Beitrag) aber was solls 😛

    *edit* oops code tags button != absenden button

    [ Dieser Beitrag wurde am 12.03.2003 um 13:57 Uhr von dreaddy editiert. ]



  • Das läuft so glatt, ohne dynamic_cast? Aber warum "befürchtet"? Du hast es doch voll im Griff. So'n kleines Schleifchen kann doch (fast) gar nicht geben.



  • void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
        Action = caFree;
    }
    


  • genau sowas habich gesucht, danke 😃

    Allerdings hab ich noch Zweifel das das einwandfrei funktioniert...
    weil:

    Programmstart: 198028 KB belegt
    100 Formulare auf: 202856 KB belegt
    alle 100 Forms geschlossen mit Action = caFree; : 202792 KB
    Programmende und Neustart des Programmes: 198272 KB

    sag mir was in den 4 MB steht das das nix macht und ich bin begeistert 😃

    edit:
    hm meine obige lösung is noch grottiger merkich grade 😞

    Programmstart: 184064KB belegt
    100 Formulare auf: 18812KB belegt
    alle 100 Forms geschlossen mit meinem obigen müllsammler; : 188652KB
    Programmende und Neustart des Programmes: 184016KB

    is die CLX wirklich so dämlich in bezug auf Forms wieder löschen?

    [ Dieser Beitrag wurde am 12.03.2003 um 15:33 Uhr von dreaddy editiert. ]



  • Natürlich ist die Qualität der Freigabe auch abhängig von der Speicherverwaltung des Systems. Es ist normal, daß Resourcen nicht unbedingt sofort wieder völlig aus den Speicher entfernt werden. Ein wiederholter Aufruf eines Prozesses erfolgt ja normalerweise deutlich schneller als der Erstaufruf.

    Mach also auch noch den Test, deinen Versuch mehrfach zu wiederholen. Belassen mehr geöffnete Fenster auch mehr Rest im Speicher. Adiert sich gar der Rest bei mehreren Versuchsreihen? Darauf kommt es letztendlich an.

    Sorry, hatte an Action = caFree; gar nicht gedacht. Das sollte der sauberste und beste Weg sein.



  • hm.. irgednwas stimmt da dochnicht... Das er die ein wenig im Hinterkopf behält ist ja ok aber jetzt ein paarmal durchgezogen mit Action = caFree; und jeweils 100 Forms neu auf und zu:

    start: 157480
    open: 163132
    close: 163004
    open: 165040
    close: 165016
    open: 166912
    close 166964
    open: 168776

    hat win eine "wenn ram da ist müll es dicht bis es vom wem anders gebraucht wird" Funktion oder wie? Jedenfalls bruach ich die Dinger definitiv danach nicht mehr, das muss man win doch klar machen können.
    Wenn ich eine eigene Klasse neu anlege und wieder delete macht er das doch auch vernünftig.

    Oder liegt das vieeicht dadran das ich die recht junge CLX benutze? Ich kann mir aber nicht vorstellen das die unter windows was andres macht als die VCL(abgesehen davond as sie weniger ist 😃 )

    [ Dieser Beitrag wurde am 13.03.2003 um 08:24 Uhr von dreaddy editiert. ]



  • hm,

    dann scheint mir die Lösung mit den vector doch besser zu sein...



  • @dreaddy, um noch mal auf deine Frage einzugehen, ich würde nicht davon ausgehen, daß für die CLX extra ein abgespecktes Klassensystem aufgebaut wurde, noch dazu mit gleichen Bezeichnern. caFree sollte die gleiche Wirkung haben wie in der VCL.

    Ein Rest für den Prozess-Typ im Speicher ist normal. Da du WIN ansprichst, starte mal zB. den netscape unter Linux zweimal hinternander. Ein Beispiel, bei dem der Unterschied deutlich auffällt.

    Das schafft Ernüchterung gegenüber dem vermeindlichen Komplettabräumer caFree. Hab das bei dem geringen hier vorkommenden Fensterumfang noch nicht getestet.


Anmelden zum Antworten