Entwickler-Ecke

Sonstiges (Delphi) - FindForm


jaenschi - Fr 25.02.05 21:00
Titel: FindForm
Hallo,
ich suche eine Funktion mit der ich eine dynamisch erstellte Form anhand ihres Namens finden kann.
Gibt es sowas oder wie kann ich da vorgehen?
Ich möchte das dann so in der Art ansprechen:

Delphi-Quelltext
1:
findform('test').Caption:='Test';                    


ScorpionKing - Fr 25.02.05 21:09

du kannst die handles bekommen, aber das handle dann wie eine form anzusprechen klappt nicht!

MfG, Scorpion!


jaenschi - Fr 25.02.05 21:15

Gibt es da keine Möglichkeit?
Man könnte auch sagen, ich habe ein String-Variable mit dem Namen des Fensters und möchte dann Proceduren des Forms nutzen, das den Namen des Wertes der Stringvariable hat. Den Namen der Stringvariable weiß ich aber vor dem Ausführen noch nicht!


wulfskin - Fr 25.02.05 21:21

Hallo,

speicher die dynamisch erstellte Form doch in einem Array/Liste/globale Variable. Dann kannst du später bequem darauf zugreifen.

Gruß Hape!


ScorpionKing - Fr 25.02.05 21:21

wenn das ginge..... *träum*
du kannst das fenster verstecken, den titel ändern etc. aber du kannst keine funktionen oder proceduren davon verwenden!


wulfskin - Fr 25.02.05 21:31

Wenn die Methoden Teil der Klasse sind, sollte das kein Problem darstellen, so fern sie öffentlich deklariert sind.

Gruß Hape!


jaenschi - Fr 25.02.05 22:08

Jetzt muss ich aber die Objekte auf dem Form ansprechen.
Also z.B.:  findform('test').Edit1.Text:='test';
Ist das überhaupt möglich?


Sprint - Fr 25.02.05 22:21
Titel: Re: FindForm
jaenschi hat folgendes geschrieben:
ich suche eine Funktion mit der ich eine dynamisch erstellte Form anhand ihres Namens finden kann.

Kommt drauf an wie du deine Form erstellt hast und ob du mit "Name" den Fenstertitel oder die Eigenschaft "Name" meinst.
FindComponent von TApplication bietet dir auf jeden Fall eine Möglichkeit.


IngoD7 - Sa 26.02.05 12:23

ScorpionKing hat folgendes geschrieben:
wenn das ginge..... *träum*
du kannst das fenster verstecken, den titel ändern etc. aber du kannst keine funktionen oder proceduren davon verwenden!

Kannst aufwachen. Das geht natürlich.

Mit dem Namen der Komponente, der Methode FindComponent und evt. mit Typumwandlungen kann man auf alle Teile einer dynamisch erzeugten Komponente zugreifen.

Um beim Beispiel/Wunsch von jaenschi zu bleiben, hier gleich ein Beispiel. Bemerkung vorab: Ich würde das so nie programmieren, sondern die dynamisch erzeugten Komponenten in Arrays ablegen oder einzelnd in var deklarieren, um sie dann per MyVariable:=TTyp.Create() zu erzeugen und später dann über MyVariable darauf zuzugreifen.
Das folgende Beispiel gilt also nur der Verdeutlichung dessen, was alles geht.
Es werden dort sehr wohl Eigenschaften und Methoden der Komponenten bearbeitet/benutzt.

Es ist ein Form mit 5 Buttons drauf. Die Funktion der Buttons geht aus ihrem Namen (siehe Name der jeweiligen OnClick-Routine) hervor:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TForm1.BtnNeueFormErstellenClick(Sender: TObject);
//Neue Form mit Edit drauf dynamisch erstellen und anzeigen
begin
with TForm.Create(Application) do
  begin
  name := 'NeueForm';
  visible := true;
  end;
with TEdit.Create(Application.FindComponent('NeueForm')) do
  begin
  name := 'NeuesEdit';
  parent := TForm(Application.FindComponent('NeueForm'));
  end;
end;

procedure TForm1.BtnEditMitAnderemTextFuellenClick(Sender: TObject);
begin
TEdit(TForm(Application.FindComponent('NeueForm')).FindComponent('NeuesEdit')).Text := 'Geht doch';
end;

procedure TForm1.BtnEditLeerenClick(Sender: TObject);
begin
TEdit(TForm(Application.FindComponent('NeueForm')).FindComponent('NeuesEdit')).Clear;
end;

procedure TForm1.BtnNeueFormVersteckenClick(Sender: TObject);
begin
TForm(Application.FindComponent('NeueForm')).Hide;
end;

procedure TForm1.BtnNeueFormAnzeigenClick(Sender: TObject);
begin
TForm(Application.FindComponent('NeueForm')).Show;
end;


@jaenschi
Schau dir das mal in Ruhe an.
Solltest du das mal ausprobieren wollen - den ersten Button musst du dann als erstes einmal drücken, damit das neue Form und das neue Edit erstmal erzeugt sind.


jaenschi - Sa 26.02.05 16:32

Pefekt! :D Genau sowas habe ich gesucht! Funktioniert super!:)


jaenschi - Sa 26.02.05 17:41

Hab nochmal eine Frage:
Ich habe jetzt folgenden Code geschrieben, um einen Button zu deaktivieren:

Delphi-Quelltext
1:
TButton(TForm(Application.FindComponent('id'+id)).FindComponent('Button1')).Enabled:=False;                    

Da gibt er mir allerdings einen Speicherfehler aus!
Wenn ich nur

Delphi-Quelltext
1:
TForm(Application.FindComponent('id'+id)).Enabled:=False;                    

schreibe, dann deaktiviert er das Form(logisch;))
Der Fehler muss also irgendwie mit dem zweiten FindComponent zu tun haben!?


Sprint - Sa 26.02.05 18:22


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  C: TComponent;
begin

  C := Application.FindComponent('id' + id);
  if Assigned(C) and (C is TForm) then
  begin
    C := C.FindComponent('Button1');
    if Assigned(C) and (C is TButton) then
      (C as TButton).Enabled := False;
  end;


jaenschi - Sa 26.02.05 19:02

Ist der Code getestet?
Weil bei

Delphi-Quelltext
1:
(C as TButton).Enabled := False;                    

verursacht er bei mir immer ein Speicherfehler :?


Sprint - Sa 26.02.05 19:08

jaenschi hat folgendes geschrieben:
Ist der Code getestet?

Natürlich.
Zitat:
Weil bei verursacht er bei mir immer ein Speicherfehler

Ich weiß nicht, was du vorm PC so machst.


jaenschi - Sa 26.02.05 19:13

Ups! Hab mich vertan. Der Speicherfehler passiert erst danach. :oops:
Dein Code ist natürlich perfekt;)


IngoD7 - Sa 26.02.05 19:55

jaenschi hat folgendes geschrieben:
Ich habe jetzt folgenden Code geschrieben, um einen Button zu deaktivieren:
TButton(TForm(Application.FindComponent('id'+id)).FindComponent('Button1')).Enabled:=False;
Da gibt er mir allerdings einen Speicherfehler aus!

Wenn es einen Button mit Namen "Button1" auf dem Form gibt, dann funktioniert das auch!

Dass man trotzdem Sicherungen einbauen sollte (welche auch immer), ist eine andere Sache.

Kleine Anmerkung zum Code von Sprint (siehe Bemerkungen im Code):

Sprint hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var
  C: TComponent;
begin

  C := Application.FindComponent('id' + id);
  //if Assigned(C) and (C is TForm) then      //Doppelte Prüfung auf nil.
  if (C is TForm) then                    //So reicht es aus.
  begin
    C := C.FindComponent('Button1');
    //if Assigned(C) and (C is TButton) then  //Doppelte Prüfung auf nil.
    if (C is TButton) then                //So reicht es aus.
      (C as TButton).Enabled := False;      
  end;


Sprint - Sa 26.02.05 20:48

@IngoD7: Immer noch besser als:
IngoD7 hat folgendes geschrieben:

Delphi-Quelltext
1:
TEdit(TForm(Application.FindComponent('NeueForm')).FindComponent('NeuesEdit')).Text := 'Geht doch';                    



@jaenschi:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  C: TComponent;
begin

  C := Application.FindComponent('id' + id);
  if Assigned(C) then
    if (C is TForm) then
    begin
      C := C.FindComponent('Button1');
      if Assigned(C) then
        if (C is TButton) then
          (C as TButton).Enabled := False;
    end;

end;


IngoD7 - Sa 26.02.05 21:37

Sprint hat folgendes geschrieben:
@IngoD7: Immer noch besser als:
IngoD7 hat folgendes geschrieben:

Delphi-Quelltext
1:
TEdit(TForm(Application.FindComponent('NeueForm')).FindComponent('NeuesEdit')).Text := 'Geht doch';                    

Warum so giftig?

Aus meinen Postings geht doch klar hervor, dass a.) ich das Beispiel nur zur Verdeutlichung der programmtechnischen Möglichkeiten so gebracht habe und b.) Sicherungen natürlich sinnvoll sind.

Zu deinem Code:
Ich glaube, du hast mich missverstanden.
Das Assigned ist immer noch überflüssig. Assigned(C) ergibt false, wenn C = nil ist. Die is-Abfrage ergibt (unter anderem) ebenfalls false, wenn C = nil ist. Deshalb ist die is-Abfrage alleine ausreichend.


Sprint - Sa 26.02.05 21:42

IngoD7 hat folgendes geschrieben:
Ich glaube, du hast mich missverstanden.

Ich habe dich schon richtig verstanden. Das liegt nur daran, dass ich mir das angewöhnt habe, jeden Zeiger bzw. Objektreferenz zu überprüfen. Genau so überprüfe ich jedes Fensterhandle mit IsWindow.