kp, warum da ein Fehler ist! - verschiedeneForm zusammengeführt



  • Hi!

    Ich hab zu einem parent-Form verschiedene Forms hinzugefügt. Alleine funzen die Forms absolut einwandfrei.
    Nach dem zusammenführen hab ich folgendes Problem:
    In nur einem von den 3 Forms, die ich zusammengeführt hab, gibt es immer,
    wenn ich auf ein Element (z.B. auf einen Button klicken, radio-button->Checked=true setzten)
    zugreifen will, eine Fehlermeldung:
    Zugriffsverletzung bei Adresse ... . Lesen von Adresse ... .
    Außerdem gibt es beim Start des Programms auch diese Fehlermeldung (andere Adressen).

    Hier ein Code-Ausschnitt:
    Project1.cpp:

    #include <vcl\vcl.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    USERES("Project1.res");
    USEFORM("Unit1.cpp", Form1);
    USEFORM("apache_configure\configure.cpp", form_configure);
    USEFORM("kiga_fileshare\fileshare.cpp", form_fileshare);
    USEFORM("kiga_fileshare\neuer_ordner.cpp", neu_ordner);
    USEFORM("kiga_start\star.cpp", form_start);
    //---------------------------------------------------------------------------
    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	try
    	{
    		Application->Initialize();
    		Application->CreateForm(__classid(TForm1), &Form1);
    		Application->Run();
    	}
    	catch (Exception &exception)
    	{
    		Application->ShowException(&exception);
    	}
    	return 0;
    }
    

    Unit1.cpp:

    //---------------------------------------------------------------------------
    #include <vcl\vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    
    #include "kiga_start/star.h"
    #include "kiga_fileshare/fileshare.h"
    #include "kiga_fileshare/neuer_ordner.h"
    #include "apache_configure/configure.h"
    
    #include <string.h>
    #include <stdio.h>
    
    //---------------------------------------------------------------------------
    #pragma resource "*.dfm"
    TForm1 *Form1;   
    Tform_fileshare *form_fileshare;
    Tform_start *form_start;
    Tform_configure *form_configure;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
     	String params;
    	for (int i=1;i<=ParamCount();i++){
    		params += ParamStr(i);
    	}
    
    	form_fileshare = new Tform_fileshare(Application);
    
    	if(strcmp(params.c_str(),"tausch")==0){
    		form_fileshare->Show();
    	}
    	else if(strcmp(params.c_str(),"sichern")==0){
    		form_fileshare->Show();
    	}
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
    	form_fileshare->Show();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
    

    fileshare.cpp:

    //---------------------------------------------------------------------------
    __fastcall Tform_fileshare::Tform_fileshare(TComponent* Owner)
    	: TForm(Owner)
    {                        
     parameters = ParamStr(1);
     if(strlen(parameters.c_str())==0){
      parameters = Form1->fileshare_var;
     }
     if(strcmp(parameters.c_str(),"tausch")==0){
    //  Rtausch->Checked=true;                  //wenn nicht auskommentiert, gibt es den Fehler. So gibt es keinen
     }
     else{
    //  Rsave->Checked=true;                    //wenn nicht auskommentiert, gibt es den Fehler. So gibt es keinen
     }
    }
    

    Wenn ich auf die Zeilen einen Haltepunkt setzte, gibt es trotzdem den Fehler. Er scheint also schon viel Früher zu kommen.

    Den Quelltext für die anderen Form (erstellen, ...) hab ich weggelassen, ist nämlich genauso wir der, der da ist.

    Noch ne Frage:
    Wie mach ich das, dass ein Form, das im Form-Create des Hauptformulars (siehe Unit1.cpp; TForm1::FormCreate()) erstellt wird, beim beenden nicht nur sich, sondern auch das Hauptfenster mit beendet? Also irgendwas ins Tform_fileshare::FormClose() rein. Habs schon mit Form1->Close() versucht, geht aber net. 😞





  • Ich benutz doch gar nicht onCreate, sondern Form1::FormCreate().
    Oder hab ich da was falsch verstanden?



  • Lies mal den von Jansen verlinkten Beitrag und beantworte dir dann deine Frage selbst.



  • Nagut, aber wie soll ich denn den folgenden Code ohne FormCreate-Methode in mein Prog einbauen??

    __fastcall Tform_fileshare::Tform_fileshare(TComponent* Owner)
    	: TForm(Owner)
    {
     parameters = ParamStr(1);
     if(strlen(parameters.c_str())==0){
      parameters = Form1->fileshare_var;
     }
     absoluter_pfad=ExtractFilePath(Application->ExeName);
    
     cr_pfad = absoluter_pfad + "htdocs\\kiga_programme\\ChildReport\\";
     f_pfad = absoluter_pfad + "htdocs\\kiga_programme\\Fahrtenbuch\\";
    
    // CRread_in(cr_pfad);
    // Fread_in(f_pfad);
    
    // CRcheck_all_items(true);
    // Fcheck_all_items(true);
     //==========================
     laufwerk_save = char('C');
     pfad_save = "C:\\";
     ordnername_save = "RES_KiGa-Software_" + datum() + "\\";
    
     laufwerk_share = char('C');
     pfad_share = "C:\\";
     ordnername_share = "Tauschdaten - KiGa-Software\\";
    
     if(strcmp(parameters.c_str(),"tausch")==0){
    //  Rtausch->Checked=true;
     }
     else{
    //  Rsave->Checked=true;
     }
    
     if(strcmp(parameters.c_str(),"uninstall")==0){
      beendenverboten = true;
    //  Rtausch->Enabled = false;
     }
    // check_Radiobuttons();
    }
    


  • __fastcall TForm1::TForm1(TComponent* Owner) 
        : TForm(Owner) 
    { 
        String params;
        for (int i=1;i<=ParamCount();i++){
            params += ParamStr(i);
        }
    
        form_fileshare = new Tform_fileshare(Application);
    
        if(strcmp(params.c_str(),"tausch")==0){
            form_fileshare->Show();
        }
        else if(strcmp(params.c_str(),"sichern")==0){
            form_fileshare->Show();
        }
    }
    

    ich bin mir nicht sicher aber ich glaub so wars gemeint

    PS: onCreate = FormCreate



  • Bin gar nich drauf gekommen, dass das gemeint sein könnte. Es gibt aber immer noch eine Fehlermeldung: EAccesViolation. Diese kommt aber nur noch, wenn das Prog über Parameter gestartet wirdund zwar in dem moment, wo das Fenster erstellt werden soll. Hab keine Ahnung, warum 😕 . 😞

    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {         
     	String params;
    	for (int i=1;i<=ParamCount();i++){
    		params += ParamStr(i);
    	}
    
    	if(strcmp(params.c_str(),"tausch")==0){
    		form_fileshare->Show();            //Hier Fehler
    	}
        else if(strcmp(params.c_str(),"sichern")==0){
    		form_fileshare->Show();            //Hier Fehler
        }
    	else if(strcmp(params.c_str(),"configure")==0){
    		form_configure->Show();            //Hier Fehler
    	}
    	else if(strcmp(params.c_str(),"start")==0){
    		form_start->Show();                //Hier Fehler
    	}
    }
    


  • Existieren die Formulare ? mit new erstellt ? oder fest eingebunden?



  • Anzuraten ist in deinem Fall, dass du alle 5 Formalare automatisch erstellen lässt.

    Dann kannst du getrost die Routinen den einzelnen Formularen bei deren OnCreate zuordnen.

    Anders wirst du erstmal nicht weiterkommen trotz aller Hinweise bisher.

    MfG
    kpeter



  • Wenn es noch so ist, wie im ersten Posting, werden die Formulare weder automatisch erzeugt (in der Project.cpp sind keine CreateForm-Anweisungen für die Formulare), noch erstellt er sie manuell. Kann also nichts anderes geben als eine Access-Violation, weil er zwar Zeiger deklariert, aber keine Instanzen erzeugt.

    Aber selbst wenn er sie automatisch erstellen läßt, nützt ihm das nichts, das sie zu dem Zeitpunkt, wo der Konstruktor des Hauptforms aufgerufen wird, noch nicht erzeugt wurden. Dies würde aber auch in OnCreate nicht funktionieren...

    Meiner Meinung nach ist der einzige sinnvolle Weg, die abhängigen Formulare komplett dynamisch zu erzeugen.

    Auf jeden Falls sollte er erstmal alles wieder löschen, was er da manuell 'reingefrickelt' hat. So ist das nämlich nichts halbes und nichts ganzes...

    Dann einfach nur die Header einbinden und die Instanzen manuell erzeugen.



  • @Joe_M.

    Joe_M. schrieb:

    Wenn es noch so ist, wie im ersten Posting, werden die Formulare weder automatisch erzeugt (in der Project.cpp sind keine CreateForm-Anweisungen für die Formulare), noch erstellt er sie manuell.

    Das Hauptformular wird , wenn es noch wie im ersten Posting ist, dort in Listing 1, Zeile 16 erzeugt.

    Während sich Form1 erstellt, soll es (nach Listing 2, Zeile 34) das form_fileshare erstellen und anzeigen. Bumm...

    Da der Autor diesen Zusammenhang bisher nicht erkannt hat, mein vorheriges Posting.

    MfG
    kpeter



  • Ich erzeuge alle Forms ganz am Anfang:

    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	try
    	{
    		Application->Initialize();         
    		Application->CreateForm(__classid(TForm1), &Form1);
    		Application->CreateForm(__classid(Tform_configure), &form_configure);
    		Application->CreateForm(__classid(Tform_fileshare), &form_fileshare);
    		Application->CreateForm(__classid(Tneu_ordner), &neu_ordner);
    		Application->CreateForm(__classid(Tform_start), &form_start);
    		Application->Run();
    	}
    	catch (Exception &exception)
    	{
    		Application->ShowException(&exception);
    	}
    	return 0;
    }
    

    Hab den Teil, der die Forms bei Parametern zeigen soll, in OnActivate gepackt. So funzt das. 🙂
    Aber jetzt gibt es beim Aufruf vom Form1->Hide(); nen Fehler, dass das nicht verändert werden darf. 😞 Hab den Aufruf überall ausprobiert. 😞



  • So funktioniert es:

    void __fastcall TForm1::FormActivate(TObject *Sender)
    {
     	String params;
    	for (int i=1;i<=ParamCount();i++){
    		params += ParamStr(i);
    	}
        fileshare_close = true;     
    
    	if(strcmp(params.c_str(),"tausch")==0){     
            SetWindowPos(Handle,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW);
        	fileshare_var = "tausch";
    		form_fileshare->Show();
    	}
        else if(strcmp(params.c_str(),"sichern")==0){  
            SetWindowPos(Handle,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW);
        	fileshare_var = "sichern";
    		form_fileshare->Show();
        }
        else if(strcmp(params.c_str(),"uninstall")==0){  
            SetWindowPos(Handle,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW);
        	fileshare_var = "uninstall";
    		form_fileshare->Show();
        }
    	else if(strcmp(params.c_str(),"configure")==0){   
            SetWindowPos(Handle,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW);
    		form_configure->Show();
    	}
    	else if(strcmp(params.c_str(),"start")==0){
            SetWindowPos(Handle,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW);
    		form_start->Show();
    	}
    }
    

    THX für eure Bemühungen



  • Hallo

    strcmp(params.c_str(),"tausch")==0
    

    Dann doch lieber

    params.Pos("tausch")==1
    

    bis bald
    akari



  • Wenn schon, dann noch einfacher mit

    if(params == "tausch")
    

    Aber warum werden zuerst alle Parameter wieder zu einem String 'params' zusammengefügt und dann abgefragt? Es reicht doch, einfach ParamStr(1) abzufragen...



  • Hallo

    Deine Version vergleicht ob params genau "tausch" entspricht. Ich habe die Überprüfung so übernommen wie es im Original ist : ob params mit "tausch" anfängt.

    Ich bin davon ausgegangen das mehr als nur dieses Codewort in den Parametern übergeben wird, deshalb auch die Zusammenfassung in einem AnsiString. Wenn allerdings nur genau ein Codewort ohne weitere Daten übergeben wird ist natürlich deine Version besser.

    bis bald
    akari



  • Nur so als Klarstellung:

    if(strcmp(params.c_str(),"tausch")==0)
    

    Hier wird auch nur verglichen, ob in der Variablen 'params' genau der String "tausch" steht, d.h. inclusive des abschließenden Null-Zeichens.
    Ansonsten müßte man in C strncmp benutzen.

    Aber in C++ und mit Mittels der VCL bzw. des Datentyps AnsiString sollte sowieso keine reine C-Funktion aufgerufen werden.

    Ich persönlich finde den Vergleich mit Pos() nicht so schön, da bei einem langen String erst der gesamte String durchsucht wird (wenn der Teilstring NICHT zu Beginn enthalten ist). Dann lieber SubString() benutzen...



  • Ich hatte den Quelltext für die Params einfach hier im Forum gefunden und benutzt. Darum hatte ich mich halt noch nicht gekümmert. Ich werd eure Tipps aber beachten 😃 .


Anmelden zum Antworten