![]() |
Programmcode geschickter schreiben
Hallo,
ich habe eine Prozedur, die mir verschiedene Controls erstellt, die Parameter wie Name, Titel, Position werden für jede neue Komponente gleich übergeben. Also den Block mit (Name := AName; ...) hätte ich dann sehr oft. Die Komponenten basieren aber alle auf einer Basisklasse, welche die meisten oben aufgelisteten Parameter schon enthält.
Code:
Nun stellt sich mir die Frage, wie macht man sowas am besten, vorallem muss man beachten das ich die Controls noch in eine Liste (TList) einfügen möchte um sie später wieder freigeben zu können, bzw. um Benutzereingaben zu erhalten. Da müsste man oben dann noch (var NewIEdit:TIEdit ...) einbauen.
TIBasic
|-TIEdit |-TIComboBox |-TIComboBoxList Dies ist mein aktueller Ansatz:
Delphi-Quellcode:
TIComponent = (IEdit,IComboBox,IComboBoxList, ...)
procedure TComponentManager.NewControl(AType:TIComponent; AName,ATitle,AValue,AHint,AList:String; ALeft,ATop,AWidth,AHeight:Integer); begin case AType of IEdit: with TIEdit.Create(FWorkPanel) do begin Name := AName; Title := ATitle; Hint := AHint; Value := AValue; Left := ALeft; Top := ATop; Width := AWidth; Height := AHeight; end; IComboBox: with TIComboBox.Create(FWorkPanel) do begin Name := AName; Title := ATitle; Hint := AHint; Value := AValue; Left := ALeft; Top := ATop; Width := AWidth; Height := AHeight; end; IComboBoxList: TIComboBoxList.Create(FWorkPanel); IPicture: TIPicture.Create(FWorkPanel); {noch einige mehr ...} end; // FControlList.Add() end; |
Re: Programmcode geschickter schreiben
Das lässt sich mit dem Einsatz von Metaklassen lösen.
Ungefähr so:
Delphi-Quellcode:
TIComponent = (IEdit,IComboBox,IComboBoxList, ...)
TIComponentMeta = class of TIComponent; procedure TComponentManager.NewControl(AType:TIComponentMeta; AName,ATitle,AValue,AHint,AList:String; ALeft,ATop,AWidth,AHeight:Integer); var IComponent : TIComponent; begin IComponent := TIComponentMeta(AType).Create(WorkPanel); with IComponent do begin Name := AName; Title := ATitle; Hint := AHint; Value := AValue; Left := ALeft; Top := ATop; Width := AWidth; Height := AHeight; end; end; // FControlList.Add() end; |
Re: Programmcode geschickter schreiben
Ich sehe grad: TIComponent ist ja keine eigene Klasse.
Haben die Componenten IEdit,IComboBox,IComboBoxList eine gemeinsame Basisklasse? Ansonsten klappts mit TPersistentClass als Metaklasse. |
Re: Programmcode geschickter schreiben
Jo, ich habe es schon angepasst, habe extra versucht ein schönes Diagramm zu zeichnen, die Basisklasse ist TIBasic.
Leider bekomme ich beim erstellen eine Fehlermeldung. Ich weiß nicht genau, aber AType ist keine Komponente sondern einfach nur eine Integer Konstante zu einer bestimmten Komponente.
Delphi-Quellcode:
type
TIBasicMeta = class of TIBasic; procedure TComponentManager.NewControl; var IBasic:TIBasic; begin IBasic := TIBasicMeta(AType).Create(FWorkPanel); with IBasic do begin Name := AName; Title := ATitle; Hint := AHint; //Value := AValue; Left := ALeft; Top := ATop; Width := AWidth; Height := AHeight; end; case AType of IEdit: with TIEdit(IBasic) do Value := AValue; end; FControlList.Add(IBasic); end; |
Re: Programmcode geschickter schreiben
Dann vieleicht so ein Ansatz:
Delphi-Quellcode:
function TComponentManager.GetClassType(AType: Integer): TIBasicMeta;
begin case AType of 1: Result := TIEdit; {...} else raise Exception.Create( {...} ); end; end; procedure TComponentManager.NewControl(AType: Integer); overload; begin NewControl(GetClassType(AType)); end; procedure TComponentManager.NewControl(AClass: TIBasicMeta); overload; begin {...} end; |
Re: Programmcode geschickter schreiben
Hmm, es wird nur die Basisklasse erstellt, so war das nicht gewollt :(
Delphi-Quellcode:
procedure TComponentManager.NewControl(AClass: TIBasicMeta; {...});
var IBasic:TIBasic; begin IBasic := AClass.Create(FWorkPanel); // TIBasicMeta(AClass).Create with IBasic do begin Name := AName; Title := ATitle; Hint := AHint; //Value := AValue; Left := ALeft; Top := ATop; Width := AWidth; Height := AHeight; end; if AClass.ClassName = TIEdit.ClassName then TIEdit(AClass).Value := AValue; // <-- hier knallt's, da TIBasic erstellt wird und nicht TIEdit FControlList.Add(IBasic); end; |
Re: Programmcode geschickter schreiben
Ich muss wiedersprechen, es wird eine Instanze von TIEdit erstellt.
Aber die Zeile mit dem cast ist falsch. Du wandelst eine Klassenvariable in eine Instanzvariable um und weist einem Property (kein class Property) etwas zu? Das war wohl so gemeint:
Delphi-Quellcode:
if IBasic is TIEdit then
TIEdit(IBasic).Value := AValue; |
Re: Programmcode geschickter schreiben
Sorry, mein Fehler, da habe ich gestern Abend was durcheinanderbebracht, natürlich ist der Typecast auf TIBasic bezogen. Aber wenn ich in dieser Zeile:
Delphi-Quellcode:
AClass gegen TIEdit ersetzte
IBasic := AClass.Create(FWorkPanel);
Delphi-Quellcode:
bekomme ich 2 Unterschiedliche Komponenten, da im Create von TIEdit z.b. noch ein TEdit erstellt wird. Oder wenn ich mit dem Debugger Schritt für Schritt durchgehe, bzw. in dem Create von TIEdit einen Haltepunkt setzte merkt man, dass dies bei AClass.Create dies nicht aufgerufen wird. :gruebel:
IBasic := TIEdit.Create(FWorkPanel);
|
Re: Programmcode geschickter schreiben
Sind deine Konstruktoren auch richtig mit virtual/override gekennzeichnet? Welchen Wert hat AClass, wenn Du ihn mit dem Debugger auswertest?
Viele Grüße |
Re: Programmcode geschickter schreiben
Danke, virtual/override war's :wall:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz