Autor Beitrag
Ares
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 128



BeitragVerfasst: Di 02.10.07 13:51 
Hallo!

Ich bastel gerade an einer eigenen Komponente für einen Dialog. Der Dialog verfügt über mehrere Buttons (OK, Abbrechen, etc.). Unter anderem soll es die Komponente erlauben, dass der Benutzer den Typ der Buttons frei wählen kann. Es soll also möglich sein TButton, TBitBtn, TSpeedButton oder irgendeine beliebige Komponente die von TWinControl abgeleitet ist als Button zu verwenden. Alle Buttons sollen dann vom ausgewählten Typ sein.

Wie kann ich sowas machen? Wie füge ich also eine Eigenschaft zu einer Komponente hinzu, die vom Typ "Typ" bzw. "Klasse" ist? Es müsste ja etwas sein wie:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
property ButtonType: "Typ" read FButtonType write SetButtonType;
...
procedure MyComponent.SetButtonType(buttonType: "Typ");
begin
   if (buttonType is TWinControl) then FButtonType := "Typ" else
      raise Exception.Create('Button-Typ von TWinControl abgeleitet sein');
   ...
   NextBtn := FButtonType.Create;  // geht das?
end;
...


Kann das funktionieren?

Vielen Dank für Ihre Hilfe
Ares
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Di 02.10.07 18:17 
user profile iconAres hat folgendes geschrieben:
Hallo!

Ich bastel gerade an einer eigenen Komponente für einen Dialog. Der Dialog verfügt über mehrere Buttons (OK, Abbrechen, etc.). Unter anderem soll es die Komponente erlauben, dass der Benutzer den Typ der Buttons frei wählen kann. Es soll also möglich sein TButton, TBitBtn, TSpeedButton oder irgendeine beliebige Komponente die von TWinControl abgeleitet ist als Button zu verwenden. Alle Buttons sollen dann vom ausgewählten Typ sein.

Wie kann ich sowas machen? Wie füge ich also eine Eigenschaft zu einer Komponente hinzu, die vom Typ "Typ" bzw. "Klasse" ist? Es müsste ja etwas sein wie:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
property ButtonType: "Typ" read FButtonType write SetButtonType;
...
procedure MyComponent.SetButtonType(buttonType: "Typ");
begin
   if (buttonType is TWinControl) then FButtonType := "Typ" else
      raise Exception.Create('Button-Typ von TWinControl abgeleitet sein');
   ...
   NextBtn := FButtonType.Create;  // geht das?
end;
...


Kann das funktionieren?

Vielen Dank für Ihre Hilfe
Ares


Mit Bordmitteln sicher nicht. Typ oder Klasse kennt nur der Compiler, normalerweise geht das beim Compilieren unter und die exe enthält keine Informationen mehr darüber. Ausnahmen wie bei "is" oder "as" werden intern abgehandelt.

Die Felder eines Objekts sind Adressen (von Variablen oder Prozeduren) - ein Typ hat keine Adresse, eine Klasse auch nicht, zumindest solange es kein entsprechndes Objekt gibt.

Du kannst dir natürlich eine eigene Enumeration definieren (tInvalid,tInteger,tReal,...) und mit "is" arbeiten, ist aber recht umständlich. Ich verwende sowas für meine Ini-Dateien mit verschiedenen Konstruktoren:
ausblenden volle Höhe 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:
   TRKiniSettingRecord = record
     SetupControl : TControl;
     BackLink : TRKiniSettingValue;
     dirty : boolean;
     removed : boolean;
     FieldIndex : word;  { 1..FieldLength }
       case TRKiniSettingVariant of
         sv_Undef   : (vUndef : longint);
         sv_String  : (VString : string[6]);
         sv_Bool    : (vBool : boolean);
         sv_Integer : (vInteger : longint);
         sv_Real    : (vReal : double);
         sv_Color   : (vColor : TColor);
         sv_Pen     : (vPen : longint);
     end;

{...}

constructor TRKiniSettingValue.Create_String (imax : integer; IG,II : TRKiniSettingName;
                Def : ShortString; EC : array of TEdit; OwnerTable : TRKIniSettingTable);
var i : integer;
begin
sType := sv_String;
for i := 0 to High (EC) do OwnerTable.SetupControlArray[i] := EC[i];
Create_General (imax,IG,II,Def,OwnerTable);
end;

constructor TRKiniSettingValue.Create_Bool   (imax : integer; IG,II : TRKiniSettingName;
                    Def : Boolean; BC : array of TButtonControl; OwnerTable : TRKIniSettingTable);
var i : integer;
begin
sType := sv_Bool;
for i := 0 to High (BC) do OwnerTable.SetupControlArray[i] := BC[i];
Create_General (imax,IG,II,Def,OwnerTable);
end;

{...}

constructor TBPMLogSettings.CreateTable (IC : TRKIniClass);
begin
inherited Create (IC);
SetLength (SetupControlArray,70);
with BLMainForm do
  begin
  Station_Node       := TRKiniSettingValue.Create_Integer (-maxStationNo,'Station',
        'Node',0, [nil] ,self);
  Station_Description  := TRKiniSettingValue.Create_String (-maxStationNo,'Station',
        'Description','', [nil] ,self);
  Station_CommPort   := TRKiniSettingValue.Create_Integer (-maxStationNo,'Station',
        'CommPortNumber',0, [nil] ,self);
{...}


Ich lege dabei im Konstruktor der Settings-Klasse fest, welcher Typ, indem der entsprechende Konstruktor für den Eintrag aufgerufen wird.

Gruss Reinhard
SvenAbeln
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 334
Erhaltene Danke: 3



BeitragVerfasst: Di 02.10.07 19:31 
Hallo,

versuch es mal so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
property ButtonType: TWinControlClass read FButtonType write SetButtonType;
...
procedure MyComponent.SetButtonType(buttonType: TWinControlClass);
begin
   FButtonType := buttonType
   ...
   NextBtn := FButtonType.Create;  // geht das?   // Ja geht, wenn FButtontype eine Klasse ist
end;
...



dann kannst du den Typ wie folgt setzen:
ausblenden Delphi-Quelltext
1:
  MyComponent.ButtonType := TButton;  // oder TBitBtn usw