Autor Beitrag
LittleBen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mo 18.04.11 23:59 
Hallo,
ich erzeuge zur Laufzeit mehrere Objekte.
Wenn ich nun mit einen dann erzeugten Objekte etwas machen will, muss ich doch mit Strings arbeiten, oder?
Angenommen:
Durch einen Klick auf einen Button(z.b Button1) erstelle ich ein Edit-Felde, zum Beispiel Edit1.
Nun will ich durch einen Klick auf einen weiteren Button(z.b Button2) den Textinhalt des erzeugten Edit-Feldes.
Nun kann ich ja nicht Einfach im Code schreiben:
ausblenden Delphi-Quelltext
1:
showmessage(edit1.text);					


Könnt ihr mir helfen?

Viele Danke & Grüße,
Benny


// EDIT: Damit ich nicht weiter missverstanden werde. ;)

Zuerst erzeuge ich beliebig viele Editfelder:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var aEdit: TEdit;
    i: integer;
    anzahl: integer;
begin
 anzahl:= Random(20);

 for i:= 0 to anzahl do
 begin
  showmessage(inttostr(anzahl));
  aEdit:= TEdit.Create(nil);
  aEdit.Parent:= self;
  aEdit.Name:= 'Edit'+inttostr(i);
  aEdit.Text:= 'Test'+inttostr(i);
  aEdit.SetBounds(100,12+i*(aEdit.Height+4),aEdit.Width,aEdit.Height);
 end;
Und nun will ich den Text vom 12. Editfeld auslesen, wenn es dieses überhaupt gibt.

Moderiert von user profile iconNarses: Topic aus Windows API verschoben am Di 19.04.2011 um 00:11


Zuletzt bearbeitet von LittleBen am So 24.04.11 00:32, insgesamt 1-mal bearbeitet
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Di 19.04.11 00:24 
Wenn Du ein Object erzeugst, kennst Du dann nicht den Namen?

Mit Findcontrol kannst Du den Namen auch herausfinden.
Oder aber, Du hast generische Namen und nutzt ein Array of Strings, in dem Du die Namen speicherst, nachdem Du die Objecte erzeugt hast.
Oder aber, Du assoziierst zum Namen des Button einen Namen fürs Edit.
Oder aber, Du machst es ganz anders.

:)

_________________
In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege ;)

Für diesen Beitrag haben gedankt: LittleBen
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.04.11 05:55 
Am besten speicherst du dir in der Regel die erzeugten Objekte direkt, zum Beispiel in einem Array.

Je nachdem wie viele Objekte du erzeugst und wie diese zu deinen internen Daten dazugehören.
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Di 19.04.11 14:00 
Also, so erzeuge ich das Objekt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Edit:= TEdit.Create(self);
  Edit.Parent:= self
  Edit.Name:= 'Edit1';
  Edit.Text:= 'Test';
  Edit.Left:= 114;
  Edit.Top:= 48;
  Edit.Height:= 20;
  Edit.Width:= 177;

So, nun will ich den Text auslesen (durch Druck auf einen Button)
ausblenden Delphi-Quelltext
1:
showmessage(Edit1.Text);					

Das funktioniert natürlich nicht, da ich das Editfeld ja zur Laufzeit erzeuge!
Doch wie kann ich diesen Text trotzdem auslesen?

Grüße,
Benny

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

EDIT: Hab es jetzt dank dem Stichwort "FindControle" herraus gefunden! Vielen Dank!
ausblenden Delphi-Quelltext
1:
showmessage(TEdit(FindComponent('edit1')).text);					
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8549
Erhaltene Danke: 478

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 19.04.11 14:12 
Na, du erzeugst eine TEdit-Instanz zur Laufzeit und weist dieses Objekt der Variable Edit zu. Wie könnte man das dann später ansprechen?

Kleiner Tipp: In deinem Code
ausblenden Delphi-Quelltext
1:
showmessage(Edit1.Text);					

Ist genau eine Ziffer zuviel. :D

Vorausgesetzt natürlich, dass Edit keine lokale Variable ist.

_________________
We are, we were and will not be.
whitef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 202
Erhaltene Danke: 1

Windows X
Delphi XE X
BeitragVerfasst: Di 19.04.11 14:19 
mal ne frage so nebenbei...^^

was ist denn der vorteil wenn man ein objekt zur laufzeit erzeugt? ressourcenschonender?
also ich hab bis jetzt immer ein objekt.visible := false gesetzt, und falls ich mal was brauchte, das objekt.visible := true gesetzt.

mfg
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.04.11 14:27 
user profile iconwhitef hat folgendes geschrieben Zum zitierten Posting springen:
was ist denn der vorteil wenn man ein objekt zur laufzeit erzeugt? ressourcenschonender?
Wenn es viele Komponenten sind, reduziert sich die Startzeit. Wobei das zwar oft sinnvollere Wege gibt, aber nicht immer.

user profile iconwhitef hat folgendes geschrieben Zum zitierten Posting springen:
also ich hab bis jetzt immer ein objekt.visible := false gesetzt, und falls ich mal was brauchte, das objekt.visible := true gesetzt.
Dann musst du aber vorher wissen wie viele Objekte du brauchen wirst. ;-)
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Mi 20.04.11 03:44 
Mal eine bescheidene Frage: Warum nimmst Du nicht die Variable/Instanz Edit, um dieses Problem zu lösen?

ausblenden Delphi-Quelltext
1:
  Showmessage(Edit.Text);					


Wie Gausi schon richtig erwähnte. Denn Du hast ja Edit als TEdit erzeugt. Somit ist Edit der Zeiger auf das Objekt und Du kannst alle öffentlichen Eigenschaften und Methoden der Komponente TEdit nutzen, indem Du sie über Edit ansprichst. Schau die mal an, was Der Compiler dir bei Edit beim Debuggen anzeigt. Dann siehst Du das.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.04.11 11:33 
Wenn Edit keine globale variable ist, funktioniert das nicht.
Daher sollte man das lieber mit FindControl/FindComponent lösen, weil hier auch getestet werden kann, ob es ein gültiges Control ist UND, ob es überhaupt ein Klassentyp ist, den man erwartet.

_________________
In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege ;)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 20.04.11 11:51 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Daher sollte man das lieber mit FindControl/FindComponent lösen, weil hier auch getestet werden kann, ob es ein gültiges Control ist UND, ob es überhaupt ein Klassentyp ist, den man erwartet.

Darf ich gleich prügeln, oder soll ich noch warten?

Wann immer man eine konkrete Instanz eines Objektes sowieso hat UND dazu sogar weiß, von welcher Klasse diese ist, sollte man dies dem Compiler auch mitteilen und auf solche Krücken wie FindComponent verzichten, da man wesentliche Vorteile einer typisierten Sprache verliert.

Also in dem Fall Edit als Variable entweder ans Objekt gebunden (im z.B. Private-Bereich des Forms) oder ausnahmsweise (wenn es SEHR GUTE GRÜNDE dafür gibt auch als globale Variable deklarieren.

FindComponent ist ein Anzeichen schlechten Codes!

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.

Für diesen Beitrag haben gedankt: Gausi
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.04.11 18:37 
Auch wenn ich mich wieder unbeliebt mache:

Nein.

Zwei Beispiele:

In einem Programm von mir ist es dem Benutzer gestattet diverse Controls in n-facher Ausführung darzustellen. Da es nach oben (theoretisch) keine Grenze gibt, ist es Codetechnisch nicht vorhersehbar, ob ein Benutzer 100 oder nur 10 davon erzeugen lässt.

Die zweite Sache ist ein Setup mit vielen Panels, auf denen die Optionen abgebildet sind. Als Navigation nutze ich Panels als "Kopfbutton". Per Code erhalte ich den Namen des gedrückten Panel und füge dem String einen anderen Teilstring hinzu (z.B. aus "Setup_Farben" <- Kopfpanel wird "Panel_Farben_sub" <- Panel, welches angezeigt werden soll), wobei ich diesen String dann mittels Findcontrol/FindComponent suche. Wenn gefunden, ist alles ok und ich mache weiter.

Neulich hatte mir jemand etwas von wegen "Wiederverwertbarkeit" erklären wollen.
Warum dann also nicht die Möglichkeiten, die Delphi bietet nutzen und mit einer einzigen Procedure, welche in minimum einen 5-Zeiler darstellt (zwischen begin .. end;) den Code optimieren ?

Und bevor Du Dich prügeln willst, wisse bitte um die Umstände :(

Viele Grüße


Edit: RS gefunden

_________________
In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege ;)
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 20.04.11 18:54 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Nein.
...und das ist die Antwort auf welche Frage?
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
In einem Programm von mir ist es dem Benutzer gestattet diverse Controls in n-facher Ausführung darzustellen. Da es nach oben (theoretisch) keine Grenze gibt, ist es Codetechnisch nicht vorhersehbar, ob ein Benutzer 100 oder nur 10 davon erzeugen lässt.
Also ich würde die Instanzen in einer TList ablegen.

user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Die zweite Sache ist ein Setup mit vielen Panels, auf denen die Optionen abgebildet sind. Als Navigation nutze ich Panels als "Kopfbutton". Per Code erhalte ich den Namen des gedrückten Panel und füge dem String einen anderen Teilstring hinzu (z.B. aus "Setup_Farben" <- Kopfpanel wird "Panel_Farben_sub" <- Panel, welches angezeigt werden soll), wobbei ich diesen String dann mittels Findcontrol/FindComponent suche. Wenn gefunden, ist alles ok und ich mache weiter.

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
FindComponent ist ein Anzeichen schlechten Codes!
q.e.d.

Die logische Verknüpfung könnte man auch über die Tag-Eigenschaft des Panels lösen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Procedure TMyForm.OnPanelClick (Sender : TObject);
Begin
(*
  If Sender is TPanel Then
    If TObject (TPanel(Sender).Tag) is TPanel Then
*)

  TPanel(TPanel(Sender).Tag).Visible := True;
End;


Wenn Du für immer in deinem Kämmerlein für dich alleine programmierst, kann man solche Klimmzüge ja machen. Wenn aber jemand anderes deine implizite Verknüpfung durch Namen nicht kennt und den Code anfässt, ist deine gesamte Logik im Eimer.

Glaub BenBE: FindControl ist Müll.

_________________
Na denn, dann. Bis dann, denn.

Für diesen Beitrag haben gedankt: BenBE
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.04.11 19:18 
user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:
Also ich würde die Instanzen in einer TList ablegen.
Hier bietet sich meistens ein Dictionary an:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private
  FEditControls: TDictionary<Integer,TEdit>;
...
  FEditControls := TDictionary<Integer,TEdit>.Create;
  FEditControls.Add(900344, NewEdit);
  FEditControls.Add(100, NewEdit);
...
  FEditControls[900344].Text := '90';
...
Als Zuordnung kann man natürlich statt Integerwerten auch z.B. Strings oder wieder Objekte (zum Beispiel Datenobjekte) nehmen.

Auf diese Weise ist man sehr flexibel und das ganze ist sehr schnell, da die Schlüssel gehasht werden.
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.04.11 19:31 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Panel_Setup_Click(Sender: TObject);
var
  Dummy_String: string;
begin

  { Korrekte Setup-Seite anzeigen }
  if TControl(Sender).Parent is TPanel then
    Dummy_String := (TControl(Sender).Parent).Name;
  Dummy_String := Copy(Dummy_String, Pos('_', Dummy_String) + 1, Length(Dummy_String));

  if FindComponent('Panel_Setup_' + Dummy_String) is TPanel then
  begin
    TPanel(FindComponent('Panel_Setup_' + Dummy_String)).BringToFront;
    TPanel(FindComponent('Panel_Setup_' + Dummy_String)).Visible := True; //nur für den Fall, dass eins aus Versehen auf Visible false steht
  end;
  { Korrekte Setup-Seite anzeigen }

end;


Zwischen { Korrekte Setup-Seite anzeigen } ist das, was ich meinte. Die Tag-Eigenschaft ist für andere Sachen reserviert.
Ok, das sind jetzt 8 Codezeilen, aber dennoch sehr übersichtlich.
Wenn man in dem Beispiel jetzt noch die Strings in eine extra Datei auslagert, die man kommentiert, dann ist das die Beste Lösung für solch einen Fall, ist meine Meinung.

Und ein TPanel(TPanel(Sender).Tag).Visible := True; ist nicht nutzbar, da, sobald jemand anderes die Tag-Eigenschaft im Code ändert, ist dies sogar noch massiv schlimmer, das das, was Du mir vorgeworfen hast, alzaimar. Und "in einem Kämmerlein [..]" impliziert schon fast eine Beleidung. Nur, weil jemand (ich) "nur" ein Hobbyprogrammierer ist, der sich sein Wissen durch Lesen angeeignet hat, sollte man hier nicht persönlich werden, bitte!

Mein Standpunkt steht fest, ich NUTZE die Möglichkeiten, die Delphi bietet, sofern mir diese bekannt sind und lerne gern dazu.
Mehr schreibe ihc hier im Beitrag nicht.

Danke für die Aufmerksamkeit, schönes Osterfest.


Edit:

@jaenicke:
Ab welcher Delphiversion ist das, was Du da geschieben hast, nutzbar? ( [..] Hier bietet sich meistens ein Dictionary an [..] )
Mein Delphi 7 kennt sowas nicht.

_________________
In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege ;)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.04.11 19:42 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
@jaenicke:
Ab welcher Delphiversion ist das, was Du da geschieben hast, nutzbar? ( [..] Hier bietet sich meistens ein Dictionary an [..] )
Mein Delphi 7 kennt sowas nicht.
Das geht ich denke ab Delphi 2009, denn ab da gibt es Generics in Delphi. Ich selbst benutze das mit Delphi XE.

Vorher kann man es mit zwei TList-Objekten relativ gut nachbilden. Es sieht dann zwar nicht ganz so elegant aus, funktioniert aber auch sehr gut.
Es ist aber immer noch übersichtlicher (und natürlich deutlich schneller) als mit FindComponent.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 20.04.11 20:34 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Mein Standpunkt steht fest, ich NUTZE die Möglichkeiten, die Delphi bietet, sofern mir diese bekannt sind und lerne gern dazu.
Mehr schreibe ihc hier im Beitrag nicht.
Und deshalb bohrt man mit dem Hammer Löcher in die Wand. Man nutzt eben die Möglichkeiten, die einem die Werkzeugkiste bietet.

_________________
Na denn, dann. Bis dann, denn.
LittleBen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: Mi 20.04.11 23:35 
Vielen Dank für eure zahlreichen Ideen.
Habe mein "Problem" nun mit FindComponent gelöst. Durch diese Funktion kann man meiner Meinung nach ein Objekt einfach und schnell finden.

Grüße,
Benny
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.04.11 23:39 
user profile iconLittleBen hat folgendes geschrieben Zum zitierten Posting springen:
Durch diese Funktion kann man meiner Meinung nach ein Objekt einfach und schnell finden.
Naja, ob das:
ausblenden Delphi-Quelltext
1:
showmessage(TEdit(FindComponent('edit1')).text);					
wirklich einfacher ist als...
ausblenden Delphi-Quelltext
1:
showmessage(Edit.text);					
Dazu sage ich mal nichts weiter... :lol:

Für diesen Beitrag haben gedankt: BenBE
beastofchaos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 247
Erhaltene Danke: 4



BeitragVerfasst: Do 21.04.11 00:19 
Seh ich auch so wie jaenicke - An dieser Stelle weist das doch eher auf einen schlechten Quelltext hin, wenn man bei nur einem Objekt schon FindComponent() benutzt.
.
Aber andererseits bohrt sich da bei mir eine Frage: Er hat doch den Namen des Objekts erst durch die Variable Edit definiert, aber danch hat er den Namen auf Edit1 umgeändert (zur LZ). Wie kann er dann ein Objekt (das Edit1 heißt) unter dem Variablennamen Edit verändern??
siehe:
ausblenden Delphi-Quelltext
1:
2:
  Edit.Name:= 'Edit1';
  Edit.Text:= 'Test';  // hier müsste doch dann Edit1.Text stehen ??
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Do 21.04.11 00:49 
Nein.

Edit = Variable:

var
Edit:TEdit;
begin
..

Wenn Edit eine Variable/Object ist, kannst/musst Du dieser/m einen Namen zuweisen.
Aber da der Name erst generiert wird, gibt es das noch nicht "physisch" auf der Form.
Daher ansprechbar per Edit, nicht per Edit1.

Die Variable/das Object könnte man auch Huzeldurf nennen. Dennoch ist es nicht unter dem Namen als Object benutzbar im Designermodus.

Und gerade WEiL es im Designmodus nicht nutzbar ist, ist es möchlich in einer ANDEREN Procedure/Function / Unit auf dieses Object/Control, welches es dann inzwischen ist, per FindControl/FindComponent zuzugreifen.

Dies erspart ViEL Arbeit im Vorfeld, da man sich nicht Gedanken machen muss, wieviele Instanzen eines Objects/Controls erzeugt werden müssen. Es sei denn, es dürfen nur z.B. 4 sein. Dann könnte man sich die Arbeit machen, die fest zu legen im Code.
Aber selbst als Array oder in einer anderen Liste, müsste diese syncronisiert werden, sollte eines der Instanzen gekillt werden.
Somit muss also wieder Code erstellt werden, der eine Liste managt.

Auch wenn ich mich widerhole: Es ist eine legitime Art ein Object/Control anzusprechen, wenn man Find... nutzt. Es ist in Delphi verfügbar, nutzbar und effizient. Leistungseinbußen gibt es in keiner Weise für "normale" Anwender.

(Ich wollte ja eigentlich nichts mehr dazu schreiben..)
^- Zu spät.

Gute Nacht.

( Ich habe meinen Hammer verlegt, muss den erst nochmal suchen -.- )

_________________
In Erfurt gibt es eine Pension, in der es gemütlich ist, Google einfach nach Pension Fiege ;)