Form nur erstellen, wenn es benötigt wird



  • Habe meinem Projekt ein Formular hinzugefügt. Nun steht in der cpp-Datei "TForm *Form2". Das heißt mit ausführen des Programms wird auch sofort dieses Formular erstellt (nur das es versteckt ist). Das möchte ich jedoch verhindern, also habe ich "TForm *Form2" rausgenommen, was leider in einem Linker-Fehler resultiert!
    Wenn ich "delete Form2" in den Konstruktor des Hauptformulars schreibe, habe ich zwar den gewünschten Effekt, aber das muss doch auch eleganter gehen?!!



  • Du mußt die Form nur aus der Liste der automatisch zu erzeugenden Formulare herausnehmen (Projekt->Optionen->Reiter Formulare) und es danne erst erzeugen, wenn Du es benötigst.

    Das könnte z.B. so aussehen:

    if (!Form2)
    	{
    		try
    		{
    			Application->CreateForm(__classid(TForm2), &Form2);
    		}
    		catch(...)
    		{
    			ShowMessage("Fehler: Form xyz kann nicht erzeugt werden.\nVorgang abgebrochen.");
    			return;
    		}
    	}
    

    Dies sollte an einer möglichst zentralen Stelle ausgeführt werden, damit Du das nicht überall einfügen mußt, wo das Formular benötigt wird. Weiterhin ist es sinnvoll im Konstruktor von Form1 (oder eben jene zentrale Stelle) den Wert von Form2 mit NULL zu initialisieren, auch wenn das eigentlich automatisch erfolgen sollte. Ein manuelles Löschen des Formulars ist nicht notwendig, da das Formular von der Application, bei Beendigung, automatisch gelöscht wird.



  • Ich versteh dein Code nicht.... Ich habe mal ein bisschen gesucht und finde es so eigentlich besser (im OnDblClick-Ereignis):

    TForm* Form2= new TForm(this)
    

    Wenn man statt this Application nimmt, dann kümmert sich das Programm zwar selbst um die Freigabe des Speichers, aber erst sehr spät.
    So muss ich mich selbst mit delete um die Freigabe kümmern, aber wie genau??
    Ich habe mal ins OnClose-ereignis von Form2 "delete this;" geschrieben, aber das resultiert in einer Zugriffsverletzung!



  • Zur Erklärung:

    if (!Form2) // existiert Form2 schon?
    	{ // nein
    		try
    		{
    			Application->CreateForm(__classid(TForm2), &Form2); // eine Instanz von TForm2 wird erzeugt und der Applications-Variable Form2 zugewiesen.
    		}
    		catch(...)
    		{  // Fehler bein Erzeugen des Formulars abfangen
    			ShowMessage("Fehler: Form xyz kann nicht erzeugt werden.\nVorgang abgebrochen.");
    			return;
    		}
    	}
    

    Diese Version ist gängig, wenn man aus Performancegründen nicht alle Formulare beim Programmstart erzeugen will, sondern erst dann, wenn sie tatsächlich benötigt werden. Sie bleiben bis zum Programmende erhalten.
    Relevant ist eigentlich nur dieser Code:

    if (!Form2)
    {
       Application->CreateForm(__classid(TForm2), &Form2);
    }
    

    Bezüglich deines Lösungsansatzes mit new:
    Du solltest nicht den Namen Form2 verwenden.
    Was immer Du dort eingibst, zur Zeit this bei der Erzeugung des Formulars steht, ist für die Löschung des Formulars verantwortlich. Wenn Du das nicht willst, kannst Du dort NULL übergeben. Dann bist Du für die Löschung des Formulars verantwortlich. Ein delete sollte sich immer im gleichen Gültigkeitsraum, wie das new befinden.
    z.B.:

    TForm2* MyForm2 = new TForm2;
    MyForm2->ShowModal();
    delete MyForm2;
    

Anmelden zum Antworten