zugriff auf dynamisch erstellten button von außen?
-
Hallo liebe Community,
ich habe Heute mit der dynamischen Programmierung angefangen und stehe nun vor meinem ersten Problem. Als erstes habe ich einen dynamischen Button im Konstruktor von der Klasse TForm1 erstellt:TButton *Test = new TButton(this); Test->Parent = this; Test->Name = "Test"; Test->Caption = "Test"; Test->Left = 32; Test->Top = 16; Test->Width = 145; Test->Height = 121; Test->OnClick = TestClick;Funktioniert auch super, jedoch möchte ich nun von einem anderen Button aus den Test-Button auf "Visible = false" setzen. Aber ich kann nicht von dem Button auf den Test-Button zugreifen. Ich habe versucht direkt auf den Test-Button zuzugreifen
Test->Visible = false;und über das Object von TForm1
Form1->Test->Visible = false;sowie über das Object von der Klasse TButton
Button->Test->Visible = false;, aber nichts davon funktioniert. Was mache ich falsch? Habe ich die Deklarierung überhaupt richtig gemacht
TButton *Test = new TButton(this);oder macht man das anders?
Vielen Dank im voraus,
DarkBug
-
Sorry, du bist hier leider im falschen Unterforum.Augen auf im Straßenverkehr

-
Erstens das und zweitens bedarf "funktioniert nicht" einer Erklärung. Sprich, du sollst sagen, wie sich der Fehler zeigt.
-
Oh, tut mir Leid, dann möge ein Moderator das bitte in das richtige Unterforum verschieben.
Zu dem Fehler:
Beim DirektzugriffTest->Visible = false;kommt einfach die Fehlermeldung, das das Object nicht existiert und wenn ich es zb. so versuche:
Form1->Test->Visible = false;kommt die Fehlermeldung, das Test kein Element von TForm1 ist.
Mfg
-
DarkBug schrieb:
kommt einfach die Fehlermeldung, das das Object nicht existiert
Die Fehlermeldung bringt dir nichts? Und poste nächstes Mal lieber die wörtliche als die interpretierte Fassung.

DarkBug schrieb:
kommt die Fehlermeldung, das Test kein Element von TForm1 ist.
Aber
Testist tatsächlich ein Member vonTForm1?
-
Ich habe jedenfalls den Button im Konstuktor von TForm1 erstellt:
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { TButton *Test = new TButton(this); Test->Parent = this; Test->Name = "Test"; Test->Caption = "Test"; Test->Left = 32; Test->Top = 16; Test->Width = 145; Test->Height = 121; Test->OnClick = TestClick; }Im Prinzip erstelle ich doch einen neuen Button der Klasse TButton in der Klasse TForm1 oder sehe ich das falsch? Ich verstehe das noch nicht so ganz. Stimmt die Deklarierung denn so?
TButton *Test = new TButton(this);
-
Du erstellst deinen Button lokal im Konstruktor deiner Form. So ist er natürlich nach außen nicht bekannt. Mach den Button Test zum Member deiner Form.
-
Nein, du erstellst eine lokale Variable, diese ist nach dem Konstruktor nicht mehr sichtbar. Du musst
Testals Membervariable in der KlasseTForm1deklarieren.
-
Das heißt ich soll den Button in der Klasse TForm1 im Header erstellen? Dann kommt eine Fehlermeldung:
Klassenelement kann hier nicht initialisiert werden.
-
Du sollst ihn dort nur deklarieren. Erstellen kannst du nach wie vor im Konstruktor.
-
Das hatte ich am Anfang so, ich kann dann zwar auf den Button extern zugreifen, jedoch bekomme ich dann für jeden Button beim starten eine Fehlermeldung:
Feld Form1->Test besitzt keine entsprechende Komponente. Soll die Deklaration entfernt werden?
Er startet das Programm zwar trotzdem, aber das kann doch so nicht richtig sein.
-
Dann hast du deinen Button wohl über den Objektinspektor eingefügt und dann den Button selbst aus der Form gelöscht? Dann meckert der Builder natürlich.
Du musst die Membervariable per Hand in den public:-Teil deiner Form einfügen.
etwa soclass TForm1 : public TForm { __published: // Von der IDE verwaltete Komponenten private: // Anwender-Deklarationen public: // Anwender-Deklarationen TButton* Test; __fastcall TForm1 (TComponent* Owner); };und dann im Konstruktor
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Test = new TButton(this); Test->Parent = this; ... }
-
Zur Laufzeit? Hmm... Ich fürchte, das hat dann nicht mehr viel mit C++ zu tun.
In diesem Sinne: Kann ein Moderator diesen Thread ins VCL-Forum verschieben?
-
Stimmt. Das wird langsam fällig.

-
Ich habe alles manuell eingefügt und nicht über irgenteinen Objektinspector. Hatte den Button zuerst unter public deklariert, jedoch kommt, wenn ich dann auf den Button klicke, der den Dynamischen Button sichtbar machen soll eine Zugriffsverletzung. Dann habe ich mich an den statischen Buttons orientiert und den Button unter published deklariert, aber dort kommt die andere Fehlermeldung.
-
DarkBug schrieb:
Ich habe alles manuell eingefügt und nicht über irgenteinen Objektinspector. Hatte den Button zuerst unter public deklariert, jedoch kommt, wenn ich dann auf den Button klicke, der den Dynamischen Button sichtbar machen soll eine Zugriffsverletzung.
Das liegt jetzt aber nicht an der Position im Header, sondern höchstwahrscheinlich an der Art und Weise, wie du deinen Button im Konstruktor initialisieren wolltest. Hast du mal deine und meine Konstruktorversion verglichen?
Ich sagen nur mal wieder "lokale Variable"
Ansonsten gibt es für diese Art von Fehlern einen Debugger, mit dem man Alles schön überprüfen kann.DarkBug schrieb:
Dann habe ich mich an den statischen Buttons orientiert und den Button unter published deklariert, aber dort kommt die andere Fehlermeldung.
Eine selbst erstellte Membervariable hat dort nichts zu suchen.
-
Das liegt jetzt aber nicht an der Position im Header, sondern höchstwahrscheinlich an der Art und Weise, wie du deinen Button im Konstruktor initialisieren wolltest. Hast du mal deine und meine Konstruktorversion verglichen?
Ich sagen nur mal wieder "lokale Variable"
Ansonsten gibt es für diese Art von Fehlern einen Debugger, mit dem man Alles schön überprüfen kann.Also war mein Button doch falsch initialisiert. Habs geändert und nun funktioniert er wie er soll. Welchen Debugger benutzt du denn?
Eine selbst erstellte Membervariable hat dort nichts zu suchen.
Ja, hätt ich selbst drauf kommen können, steht ja sogar dabei >.<.
__published: // Von der IDE verwaltete Komponenten
Könntet ihr mir vielleicht noch sagen wie ich den Destruktor von TForm1 initialisieren kann? Auf die übliche Weiße funktioniert das irgentwie nicht oder ich stell mich wieder zu blöd an >.<.
Den Destruktor möchte ich wie es normal ist dazu benutzen den Button wieder zu deleten:if(Test) { delete Test; }Könntet ihr mir erklären wozu das eigentlich gut ist? Denn es funktioniert doch auch alles so.
-
DarkBug schrieb:
Welchen Debugger benutzt du denn?
Den im BCB eingebauten.
http://www.junix.ch/bcb/help/debug.html
Zum Destruktor.
Den Destruktor einer Form musst du selber erstellen. Der würde etwa so aussehen.__fastcall TForm1::~TForm1() { ... }Die Deklaration muss noch in den public-Teil, am besten gleich unter den Konstruktor.
Wenn du deinen Button aber so erzeugst.Test = new TButton(this);dann brauchst eigentlich kein delete. Das this, was du da im Konstruktor von TButton mitgegeben hast, ist der Owner der Komponente (des Buttons). Der ist auch für das Löschen zuständig. In diesem Fall bedeutet das, dass die Form selbst schon das Löschen übernimmt.
Nur wenn du dort 0 statt this hinschreibst, musst du das löschen selbst übernehmen.
-
Zum Destruktor:
Ja, genau das habe ich auch gemacht. Bei meinen eigenen Klassen funktioniert das auch immer wunderbar, jedoch gibt es bei den Klassen von Borland immer Schwierigkeiten.Hier meine cpp:
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- __fastcall TForm1::~TForm1(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------------------------------Hier mein Header:
public: // Anwender-Deklarationen __fastcall TForm1(TComponent* Owner); __fastcall ~TForm1(TComponent* Owner);Hier der Fehler:
In Klassen im VCL-Stil definierte Destruktoren müssen virtuell sein.Zum Button:
Danke, gut zu wissen das ich kein delete brauche. Im Prinzip brauche ich folgenden Code dann doch auch eigentlich gar nicht oder?Test->Parent = this;Weil der Parent in den Runden Klammern hier
Test = new TButton(this);schon angegeben wird, oder?
-
Jetzt was zu deinen Fragen.
1. Dein Destruktor ist falsch. Der hat weder Argumente noch braucht er eine Initialisierungsliste. Sieh einfach nochmal genauer mein Beispiel an.2. Das was du beim Konstruktor deiner Komponente mitgibst ist der Owner, ist für das Löschen zuständig, und nicht der Parent. Der Parent ist die Komponente auf dem deine Komponente (Button) dargestellt wird.
Du brauchst also beides.