Problem bei Zugriff auf zur Laufzeit erstellte Komponenten
-
Moin in die Runde,
ich steh grad etwas auf dem Schlauch. Ich wollte eigtl nur, dass immer wenn jmd auf einen Button klickt, ein neues Panel erzeugt wird. Die kann man dann per Drag&Drop verschieben und über einen weiteren Button wollte ich von allen bis zu dem Zeitpunkt erstellten Panels die Koordinaten abfragen.
Das Erstellen funktioniert auch problemlos und dort kann ich dem Element auch die entsprechenden Eigenschaften zuweisen.void __fastcall TForm1::NewWaypointClick(TObject *Sender) { u++; //Zähler, der mir zeigen soll, wie viele Elemente erstellt wurden flgz = new TPanel(Application); flgz->Name = "flgz" + IntToStr (u); flgz->Caption = flgz->Name; flgz->Parent = this; flgz->Width = 150; flgz->Height = 150; flgz->Top = 88; flgz->Left = 8; flgz->ParentColor = false; flgz->ParentBackground = false; flgz->AlignWithMargins = true; flgz->Color = clRed; flgz->OnMouseDown = Panel3MouseDown; flgz->Show(); }
Wenn ich aber später bei der Positionsabfrage nochmal darauf zugreifen will, krieg ich immer ne Exception.
void __fastcall TForm1::KoordinatenClick(TObject *Sender) { List = new TStringList; for (int j=1; j<=u; j++) { TPanel *Temp=dynamic_cast<TPanel*>(Form1->FindComponent("flgz" + IntToStr(j))); List->Add(IntToStr (Temp->Top)); List->Add(InTToStr (Temp->Left)); RichEdit1->Text = List->Text; } }
Hatte das dann u.a. auch mal so probiert:
void __fastcall TForm1::KoordinatenClick(TObject *Sender) { for (int j=1; j<=u; j++) { for(int i=0; i < Form1->ComponentCount; i++) { if (Form1->Components[i]->ClassNameIs("TPanel")) { if (dynamic_cast<TPanel*>(Form1->Components[i])->Name == ("flgz" + IntToStr(j))) TPanel *Temp = dynamic_cast<TPanel*>(Form1->Components[j]); } } } }
Hab ein bisschen im Debugger experimentiert und die FAQs durchwühlt und mir ist aufgefallen, dass wenn ich mir alle Komponenten der Form durchzählen lasse, die erstellen Panels gar nicht gefunden werden. Die Buttons und Panels, die bereits im Designer erstellt wurden, geht er durch. Die anderen nicht. Ich vermute mal, dass es also irgendwas mit der Namensgebung bei der Erstellung zu tun haben muss. Hatte auch erst überlegt, die zusammen in ein Array zu erzeugen, um über nen Index leichter drauf zugreifen zu können, aber ich weiß ja noch gar nicht wie viele erzeugt werden sollen. Kann man das auch mit nem dynamischen Array lösen? Fragen über Fragen
Wäre nett, wenn mir jemand auf die Sprünge helfen könnte, warum das nicht so funktioniert bzw. wie ich es besser machen könnte
Lieben Gruß und schönen Abend!
P.S.: Achso, ich verwende übrigens C++ Builder 10.2 Starter
-
Leg die in ´nem
std::vector
ab.
-
Die Panels tauchen nicht in den Komponenten des Formulars auf, da du beim Erzeugen Application zuweist. Somit ist Application der Owner der Panels, weswegen sie den Komponenten von Application zugeordnet werden.
Versuch mal das:
flgz = new TPanel(this);
-
Ah wie blöd von mir... danke für eure Tipps, werde ich ausprobieren!
-
drummi schrieb:
void __fastcall TForm1::KoordinatenClick(TObject *Sender) { for (int j=1; j<=u; j++) { for(int i=0; i < Form1->ComponentCount; i++) { if (Form1->Components[i]->ClassNameIs("TPanel")) { if (dynamic_cast<TPanel*>(Form1->Components[i])->Name == ("flgz" + IntToStr(j))) TPanel *Temp = dynamic_cast<TPanel*>(Form1->Components[j]); } } } }
Richtig und effizienter wäre übrigens:
void __fastcall TForm1::KoordinatenClick(TObject *Sender) { for(int i=0; i <= Form1->ComponentCount; i++) { if (Form1->Components[i]->ClassNameIs("TPanel")) { TPanel *Temp = dynamic_cast<TPanel*>(Form1->Components[i]); if (tTemp->Name.SubString(0,4) == "flgz") { // Hier die Koordinaten ermitteln und irgendwo eintragen } } } }
-
So. Und jetzt noch das ClassNameIs rauswerfen und den Rückgabewert vom dynamic_cast auswerten.
-
Braunstein schrieb:
So. Und jetzt noch das ClassNameIs rauswerfen und den Rückgabewert vom dynamic_cast auswerten.
...und mit dem SubString bei index 1 anfangen
-
Richtig ist also
for (int i=0; i < this->ComponentCount; i++) { TPanel *panel = dynamic_cast<TPanel*>(this->Components[i]); if (panel != NULL) { // ... } }
(das "this->" kann man selbstverständlich weglassen oder aber man übergibt die Form als Parameter für eine allgemein benutzbare Funktion)