Zugriffsverletzung bei Zugriff auf Komponenten eines MDI-Child
-
Du überprüfst die Adressen indem du sie dir anzeigen läßt. Eine weiter Möglichkeit wäre: Klick mit der rechten Maustaste auf die Variable (z.Bsp. lagerplatz_anlegen) dann im Kontextmenü auf Fehlersuche/untersuchen gehen.
-
Ich habe jetzt mal was geändert. Über einen neuen Button gebe ich folgends aus:
anzahlchilds->Caption = MDIChildCount;Müsste da dann nicht bei einem geöffnetet Child "1" raus kommen?
Es steht bei mir nur "0".Könnte es daran liegen? Das er das Child garnicht richtig erkennt.
-
Hallo
siehe hier Abschnitt Variablen überwachen. Du kannst u.a. die ganzen einzelnen Ebenen von lagerplatz_anlegen über lagerplatz_anlegen->DBGrid1 usw. nacheinander überprüfen, um die Stelle mit der ungültigen Adresse (meistens ein 0-Zeiger) zu finden.
De Aufruf selber scheint in Ordnung, ist aber schwer ohne weiteren Code zu beurteilen.
bis bald
akari
-
Also, wenn ich mit dem Mauszeiger über lagerplatz_anlegen gehe steht da
lagerplatz_anlegen=NULLBei DBGrid1 steht
lagerplatz_anlegen->DBGrid1=????Wäre das schon der Fehler?
Edit1:
Für mich sieht das so aus, als wenn er das Fenster nicht erkennt. Als wenn es gar nicht da ist, oder nicht geöffnet ist. Das ist ja das, was ich etwas weiter oben shcon geschrieben habe. Ob bei ChildCount nicht zumindest 1 stehen müsste.
-
Das wäre ein Fehler. NULL ist ein ungültiger Pointer. Nun mußt du halt mal nachschauen warum das so ist. Wo soll lagerplatz_anlegen belegt werden? Funktioniert das?
-
Also im MainForm habe ich ein TMainMenu. Dort rufe ich lagerplatz_anlegen folgendermaßen auf:
void __fastcall Thauptmenu::Lagerplatzanlegen1Click(TObject *Sender) { bool gefunden=false; //Überprüfen ob das MDIChild besteht for (int i = MDIChildCount - 1; i >= 0; i--) { if ((AnsiString)MDIChildren[i]->ClassName() == "Tlagerplatz_anlegen") { MDIChildren[i]->Show(); gefunden=true; } } if (!gefunden) {//Fuhrpark erstellen Tlagerplatz_anlegen *lagerplatz_anlegen = new Tlagerplatz_anlegen(Application); lagerplatz_anlegen->Show(); } }Dann öffnet sich das Form. Da habe ich noch drei Edit Felder drauf. Dort kann ich auch was eingeben. Und die eingegebenen Daten speichere ich per Button in einer MySQL Datenbank.
Das funktioniert auch alles wunderbar.Verstehe deshalb auch nicht, wieso er das Formular anscheind nicht hat.
-
Hallo
In Thauptmenu::Lagerplatzanlegen1Click ist *Tlagerplatz_anlegen lagerplatz_anlegen eine lokale Variable.
Wo immer du lagerplatz_anlegen->.. aufrufst, must du noch sicherstellen, das dort auch die Adresse der erstellten Form ist. Tip : Mach lagerplatz_anlegen zu einer Member-Variablen der Form.
bis bald
akari
-
Also meinem Verständnis nach rufe ich lagerplatz_anlegen genau an der Stelle auf die ich oben schon reinkopiert habe. Das ganze steht im MainForm meines Programms.
Was genau sind denn Member-Variablen und wo geschweige denn wie erstelle ich die in meinem Fall?
-
Membervariablen, sind Variablen innerhalb deiner Form-Klasse. Schau doch mal in die Headerdatei, wo Thauptmenu deklariert wurde. Alle Variablen, die da unter private: public: etc. stehen sind Membervariablen bzw. Funktionen.
Deine Variable lagerplatz_anlegen ist lokal in Lagerplatzanlegen1Click und somit nach Verlassen dieser Funktion ungültig.
Schreibs mal soif (!gefunden) { //Fuhrpark erstellen lagerplatz_anlegen = new Tlagerplatz_anlegen(Application); lagerplatz_anlegen->Show(); }PS.
Es wäre gut, wenn du dir mal ein Grundlagentutorial zu C++ durchliest. Insbesondere alles über Gültigkeitsbereiche von Variablen und Klassen.
http://tutorial.schornboeck.net/scope.htm
http://tutorial.schornboeck.net/oop2.htm und nachfolgende Seiten
Am besten überhaupt alles.
-
@Braunstein
So funktioniert das jetzt.Was genau ist denn jetzt der Unterschied zwischen:
Tlagerplatz_anlegen *lagerplatz_anlegen = new Tlagerplatz_anlegen(Application);und
lagerplatz_anlegen = new Tlagerplatz_anlegen(Application);Im oberen wird lagerplatz_anlegen direkt in der Funktion deklariert. Wo wird es jetzt aber beim unteren deklariert?
Edit1:
Danke, werde mir die Links mal anschauen.
-
EPMS schrieb:
... Wo wird es jetzt aber beim unteren deklariert?
In der Headerdatei von Thauptmenu.
-
Hallo
das untere funktioniert nur wenn bereits eine solche Variable vorher deklariert wurde. Das kann in der selben Methode sein, das kann aber auch als Member der Form oder gar global sein.
Schau dir noch mal in einem C++Grundlagen-Tutorial Gültigskeitsbereiche/Scopes an.bis bald
akari
-
Werde mir das mal durchlesen.
Allerdings finde ich in der Headerdatei von Thauptmenu nichts bezüglich "lagerplatz_anlegen". Dort steht darüber nichts.
-
Hallo
du must doch wissen, wo du die Variable deklariert hast... Tip : benutz die IDE-Funktion zum Suchen von Text in den Projektdateien, um das zu finden.
bis bald
akari
-
Andere Variante
Halte Strg fest und klicke mit der linken Maustaste auf deine Variable in der Funktion, dann springt er zur Deklaration (dauert manchmal etwas).
-
Jetzt habe ich es gefunden. Sie werden in der Headerdatei des jeweiligen Forms deklariert.
Jetzt habe ich noch eine Frage:
- Wenn ich im OnCreate oder OnActivate folgendes eingebe:lagerplatz_anlegen->Label15->Caption = "test";Bekomme ich auch wieder eine Zugriffsverletzung. Das liegt doch dann bestimmt auch wieder daran, dass lagerplatz_anlegen noch nicht deklariert ist oder?
Edit1:
Wenn ich unter Projekt->Optionen das Formular auf "Automatisch erzeugen" stelle habe ich die Zugriffsverletzung nicht. D.h. wenn ich es nicht automatisch erzeugen lasse ist es noch nicht da und deshalb kommt die Fehlermeldung oder?Sorry wegen der vielen Fragen.
-
Die Variable ist schon deklariert. Das ist allerdings nur ein (in OnCreate ungültiger) Zeiger auf Tlagerplatz_anlegen. Erst durch aufrufen von new usw. erzeugst du eine gültige Instanz. Das gleiche geschieht automatisch wenn du das Formular in "Automatisch erzeugen" einträgst.
-
Durch meinen aufruf mit
lagerplatz_anlegen = new Tlagerplatz_anlegen(Application);erzeuge ich also eine neue gültige Instanz?
Wieso geht dann aber mein oben beschriebener Befehl nicht? Oder kann ich sowas in OnCreate oder OnActivate überhaupt nicht aufrufen?
Wenn ich es so
Label15->Caption = "test";aufrufe kommt keine Fehlermeldung. Damit wäre ich ja fast beim gleichen Fehler wie am Anfang. Das verstehe ich jetzt nicht wirklich.
*langsam am verzweifeln*
-
Lies dir einfach erstmal die Tutorials durch. Dann sollte dir das klar werden.
-
@Braunstein,
habe mir das jetzt mal angeschaut. Klingt mir alles auch sehr logisch und denke ich habe das verstanden.Leider weiß ich nicht, wo jetzt genau mein Fehler liegt. Weil nur "new" habe ich das Formular doch erzeugt. Wieso kann ich dann meinen Befehl im OnCreate oder OnActivate nicht ausführen?