Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Klassennamen ermitteln und als String ausgeben


galagher - Fr 26.02.10 16:23
Titel: Klassennamen ermitteln und als String ausgeben
Hallo!

Ich möchte einen String, der eine Komponente bezeichnet, als Klassennamen verwenden, damit die Klasse der Komponente ermitteln und als String ausgeben.
Gegeben ist zB. 'TMyButton' -> ein String, der eine Komponente bezeichnet. Ob es diese wirklich gibt oder nicht, ist zunächst egal.
Nun will ich folgenden Vergleich anstellen - Pseudocode:

Delphi-Quelltext
1:
 if Class(StringToClassName('TMyButton')) = Class(TButton) then                    

So funktioniert das natürlich nicht!
Ich möchte den String 'TMyButton' in einen echten Klassennamen umwandeln und dann prüfen, ob es eine Komponente vom Typ TButton ist.

Kann aber auch TMemo, TSpeedButton oder sonstwas sein, wobei die Strings eben auch unterschiedlich sein können. Wie mache ich das?

//Edit: oder:

Delphi-Quelltext
1:
 if ComponentName('TMyButton') = TButton then                    



Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Fr 26.02.2010 um 16:35


Xentar - Fr 26.02.10 16:55

Ich versteh die Frage nicht, aber werfe mal "FindComponent" und "Button1.ClassName" in den Raum.
Aber wieso haben deine Komponenten einen Klassennamen als Komponentennamen?


galagher - Fr 26.02.10 17:33

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Ich versteh die Frage nicht, aber werfe mal "FindComponent" und "Button1.ClassName" in den Raum.

Also: Es sind keine Komponenten, sondern Strings, die wie Komponentennamen aussehen, zB. 'TMyButton' -> ein String. Ich will nun prüfen, ob es eine Komponente namens TMyButton wirklich gibt und wovon diese abgeleitet ist, nur kann ich nicht einfach TMyButton (=den Komponentennamen angeben), weil ich nur einen String habe.
Wie prüfe ich, von welchem Vorfahr ein String, der eine Komponente sein könnte, abgeleitet ist? Klingt absurd, aber es sind tatsächlich Strings. Kurz: Was ist die zugrundeliegende Komponente? Wovon ist das abgeleitet, welcher Typ ist diese Komponente?

Ok, nochmal Pseudocode:

Delphi-Quelltext
1:
2:
3:
 Caption := FindComponent('Button1').ClassName;  //das klappt ja!
 Caption := FindComponent('TMyButton').ClassName; //das führt natürlich zu einer Zugriffsverletzung
 Caption := FindComponent(StringToComponentName('TMyButton').ClassName;  //sowas brauche ich!

Ich möchte zB. feststellen, ob eine 'TMyButton' vom Typ 'TButton' ist.
Ich habe also keinen wirklichen Button auf der Form, der Button1 heisst, sondern nur einen String, der einen Koponentenname ist. Ob es diese Komponente oder einen solchen Typ gibt oder nicht, ist nicht bekannt.

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Aber wieso haben deine Komponenten einen Klassennamen als Komponentennamen?

Ich meine Komponententypen (wie TEdit) und Klassennamen!


SvenAbeln - Fr 26.02.10 17:40

Falls die Klassen deiner Komponenten registriert sind, kannst du FindClass oder GetClass benutzen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var AClass: TPersistentClass;
begin
  AClass := GetClass('TMyButton');
  if assigned(AClass) then
    if AClass.InheritsFrom(TButton) then
...


Chemiker - Fr 26.02.10 19:37

Hallo galagher,

könnte man sowas nicht mit einen Class helper erledigen?

Beispiel:


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:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
unit uDemoClassHelperName_ClassName;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyButton = Class (TButton)
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    CheckBox1: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    MyButton1: TMyButton;
  end;


type
  TKlassenHelfer = Class helper for TComponent
    function BezKomponente : String;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyButton }

constructor TMyButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Name := 'MyButton1';
  Left := 120;
  Top := 136;
  Width := 75;
  Height := 25;
end;

destructor TMyButton.Destroy;
begin

  inherited;
end;

{ TKlassenHelfer }

function TKlassenHelfer.BezKomponente: String;
begin
  result:= 'Klassen-Name: '+ ClassName + ' Instanz: ' + Name;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage((Sender as TComponent).BezKomponente);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyButton1 := TMyButton.Create(self);
  MyButton1.Parent:= self;
  MyButton1.OnClick:= Button1Click;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MyButton1.Free;
end;

end.


Bis bald Chemiker


galagher - Fr 26.02.10 21:13

user profile iconSvenAbeln hat folgendes geschrieben Zum zitierten Posting springen:
Falls die Klassen deiner Komponenten registriert sind, kannst du FindClass oder GetClass benutzen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var AClass: TPersistentClass;
begin
  AClass := GetClass('TMyButton');
  if assigned(AClass) then
    if AClass.InheritsFrom(TButton) then
...

Funktioniert nicht mal mit 'TButton' ...
... und ich denke, TButton ist Delphi ja wohl bekannt!


galagher - Fr 26.02.10 21:15

user profile iconChemiker hat folgendes geschrieben Zum zitierten Posting springen:
Hallo galagher,

könnte man sowas nicht mit einen Class helper erledigen?

Muss ich mir erst noch ansehen ... Aber heute nicht mehr *** Feier *** !!! :D

Danke vorerst für eure Hilfe!


SvenAbeln - Fr 26.02.10 23:22

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:

Funktioniert nicht mal mit 'TButton' ...
... und ich denke, TButton ist Delphi ja wohl bekannt!


user profile iconSvenAbeln hat folgendes geschrieben Zum zitierten Posting springen:
Falls die Klassen deiner Komponenten registriert sind, kannst du FindClass oder GetClass benutzen:

Ich hab mich dabei aber von der Delphi Hilfe in die Irre führen lassen:
Zitat:
Formularklassen und Komponentenklassen, die in einer Formulardeklaration referenziert sind (Instanzvariablen), werden beim Laden des Formulars automatisch registriert. Andere Klassen können durch den von RegisterClass oder RegisterClasses registriert werden

Die Klassen werden dabei aber scheinbar nicht Global registriert, :cry: daher erweitere ich meine Lösung mal um:

Delphi-Quelltext
1:
2:
Initialization
  RegisterClass(TMyButton);


galagher - Sa 27.02.10 12:11

user profile iconChemiker hat folgendes geschrieben Zum zitierten Posting springen:
könnte man sowas nicht mit einen Class helper erledigen?

Da es sich nicht zwangsläufig um TButton und TMyButton handelt, sondern alle möglichen Bezeichnungen vorkommen können, nützt mir das leider nichts! Trotzdem danke für deine Mühe!

user profile iconSvenAbeln hat folgendes geschrieben Zum zitierten Posting springen:
daher erweitere ich meine Lösung mal um:

Delphi-Quelltext
1:
2:
Initialization
  RegisterClass(TMyButton);

Nützt mir leider auch nichts aus dem selben Grund wie oben, dennoch ebenfalls danke!

Ich bin draufgekommen, dass zB. TUpDown kein Nachfahr irgendeines TButtons oder Ähnlichem ist, sondern von TControl/TWinControl kommt. Dennoch muss er TButton zugeordnet werden. Das Überprüfen auf den Vorfahr-Typ ist also kein zuverlässiges Mittel... Ich gebe den Gedanken vorläufig also auf, so komme ich nicht weiter!