[gelöst] Zugriff auf Funktionen aus dynamisch angelegten Komponenten
-
Hallo,
das ist mein erster Beitrag in diesem Forum. Ich hoffe, dass ich hier Richtig bin.Also ich habe für ein Programm eine Komponente vom Typ TPanel erstellt. Auf diesem Panel befinden sich ca. 20 TEdit-Felder, Labels und Buttons.
Da zu Programmstart nicht klar ist, wie viele Panels benötigt werden, erstelle ich sie per Mausklick. Soweit so gut.Nun möchte ich die Eingabe von den Panels, über einen Tastendruck auf die Menüleiste des Programms, auslesen. Hierzu habe ich in die Panelkomponente zuvor eine Funktion implementiert, die die Eingabedaten an das Programm zur Auswertung liefern soll.
Lege ich die Komponente zur Entwicklungszeit an, funktioniert alles ohne Probleme. Möchte ich aber auf die Funktion der dynamisch erzeugten Komponente zugreifen geht es nicht, da sich der Quellcode nicht kompilieren lässt.
Ist irgendwie auch klar, da die Komponente noch nicht da ist, kann ich sie auch noch nicht namentlich aufrufen.
Aber irgendwie muss es doch gehen! Ich hoffe Ihr könnt meine Beschreibung verstehen und habt eine Idee.
-
Hallo
Siehe FAQ hier im Builder-Forum, Abschnitt Komponenten Benutzen, Beitrag zur Laufzeit erstellen, anzeigen und Events zuweisen
bis bald
akari
-
Erste einmal Danke für die schnelle Antwort!
Aber anscheinend sehe ich den Wald vor lauter Bäumen nicht!
Diesen Artikel hatte ich bereits gefunden, aber mir fehlt der Zusammenhang zu meinem Problem.
Die Funktion, die ich aufrufen möchte ist bereits in der Komponente vorhanden. Nur zur Entwurfzeit kann ich sie noch nicht aufrufen (benennen), da sie noch nicht angelegt ist (wird erst bei laufendem Programm dynamisch erstellt).Ich bräuchte noch einen wink mit dem Scheunentor...
-
Dann zeig mal deinen Code (der sich nicht kompilieren läßt)...
hobbysucher schrieb:
Ist irgendwie auch klar, da die Komponente noch nicht da ist, kann ich sie auch noch nicht namentlich aufrufen.
Per Namen nicht, sondern dann dynamisch per Zeiger (bzw. Index auf das angelegte Array)...
-
Siehe im gleichen FAQ-Abschnitt den Eintrag "Zugriff nicht über Namen".
-
@Th69
Also zuerst mal den Quellcode (Auszugsweise). Ich hoffe er ist ausreichend:Die Funktion in der Komponente.
(Die Funktion habe ich im Header unter "public" deklariert.)TASDaten __fastcall TAtemschutzPanel::Truppdaten_get(void) { daten.name1 = Name1Edit->Text; daten.name2 = Name2Edit->Text; daten.nametr = TruppEdit->Text; daten.startdruck1 = StartDruck1Edit->Text; daten.startdruck2 = StartDruck2Edit->Text; daten.startzeit = StartEdit->Text; daten.k1druck1 = Druck1K1Edit->Text; daten.k1druck2 = Druck2K1Edit->Text; daten.zeit1 = ZeitK1Edit->Text; daten.info1 = InfoTextK1; daten.k2druck1 = Druck1K2Edit->Text; daten.k2druck2 = Druck2K2Edit->Text; daten.zeit2 = ZeitK2Edit->Text; daten.info2 = InfoTextK2; daten.k3druck1 = Druck1K3Edit->Text; daten.k3druck2 = Druck2K3Edit->Text; daten.zeit3 = ZeitK3Edit->Text; daten.info3 = InfoTextK3; daten.k4druck1 = Druck1K4Edit->Text; daten.k4druck2 = Druck2K4Edit->Text; daten.zeit4 = ZeitK4Edit->Text; daten.info4 = InfoTextK4; daten.endzeit = endzeit; return daten; }
Also nicht großartiges. Es werden nur Strings von der Eingabe auf eine in "class" angelegte Dateistruktur übertragen.
Anlegen der dynamischen Komponente im Hauptprogramm:
void __fastcall TForm1::Neueberwachung1Click(TObject *Sender) { //Panel erstellen AtemschutzPanel[panelNr] = new TAtemschutzPanel(this); AtemschutzPanel[panelNr]->Truppdaten_set(truppF, truppM, truppN); AtemschutzPanel[panelNr]->Left = 8; if(panelNr == 0) AtemschutzPanel[panelNr]->Top = 72; else AtemschutzPanel[panelNr]->Top = 72 + 152 * panelNr; AtemschutzPanel[panelNr]->Parent = this; AtemschutzPanel[panelNr]->Show(); panelNr++; }
Der Aufruf der Funktion aus dem Hauptprogramm:
void __fastcall TForm1::berwachungsbericht1Click(TObject *Sender) { Memo1->Clear(); for(int i = panelNr-1; i >= 0; i--) { //Einsatzdaten[i] = AtemschutzPanel[panelNr]->Truppdaten_get(); //Versuch 1 Einsatzdaten[i] = dynamic_cast<TAtemschutzPanel*>(AtemschutzPanel[panelNr])->Truppdaten_get(); //Versuch 2 nach dem FAQ Beispiel Memo1->Lines->Add("Einsatzdaten " + IntToStr(i)); Memo1->Lines->Add(" "); Memo1->Lines->Add(Einsatzdaten[i].name1); . Memo1->Lines->Add(Einsatzdaten[i].enddruck2); } }
Ich hatte die Funktion noch einmal neu geschrieben. Zumindest läßt sich der Code nun kompelieren. Das neue Problem ist nun, dass ich nach dem Einspringen in der Komponentenfunktion eine Lesezugriffsverletzung bekomme. Der Cursor bleibt an der ersten Leseanweisung stehen ("daten.name1 = Name1Edit->Text;")
@akari
Ich hoffe ich habe das FAQ richtig umgesetzt!
Es macht aber keinen Unterschied ob ich "Versuch 1" oder "Versuch 2" verwende.
-
Du verwendest in deiner Schleife den falschen Index:
for(int i = panelNr-1; i >= 0; i--) { Einsatzdaten[i] = AtemschutzPanel[panelNr]->Truppdaten_get(); //Versuch 1 }
Da gehört wohl statt "panelNr" der Index "i" hin...
Kein Wunder also, daß du eine Zugriffsverletzung bekommst.
P.S. Den dynamic_cast<> benötigst du nur, wenn deine Liste "AtemschutzPanel" als TControl, TPanel o.ä. angelegt wurde. Wenn es schon direkt als "TAtemschutzPanel" angelegt ist, dann reicht Version 1 (da ja kein Compilerfehler erscheint -).
-
Das ist unglaublich
ich weiß nicht wie oft ich diese Zeile geschrieben (nicht kopiert) habe. Immer wieder falsch, unglaublich ...
Auf jeden Fall, vielen Dank. Das Programm läuft jetzt so wie geplant.