Delphi-Komponenten- und Eigenschaften-Editor
(1) Vorwort
In diesem Artikel wird anhand eines Beispiels die Komponentenentwicklung und der Eigenschaftseditor beschrieben.
Das Beispiel (TdsWaitDialogEx) ist eine visuelle Komponente, die einen Dialog anzeigt, nachdem ihre Show-Methode aufgerufen wurde.
Es enthält ein TAnimate, zwei Eingabeaufforderungsmeldungen (z. B. TLabel) und einen Fortschrittsbalken (TGauge).
Aufzählungseigenschaften: DialogStyle, AViposition
Datensatzeigenschaften: Optionen
Das Eigenschaftensammlungsobjekt erbt von TPersistent. In diesem Beispiel enthält die AVISource-Eigenschaftensammlung TAnimate
Animationseigenschaften CommonAVI, FileName
Der Eigenschafteneditor wird mit der FileName-Eigenschaft von AVISource angewendet, d. h. beim Bearbeiten wird ein String FileName angezeigt.
TOpenDialog, sein Filterfilter ist *.avi
(2) Komponentenpaket dsDlgPack.dpk
Um die Veröffentlichung, Installation usw. zu erleichtern, muss das Komponentenpaket .dpk verwendet werden.
In Versionen nach Delphi6 (ich weiß nichts über Versionen vor D5) gibt es mehrere Dateien, die Delphi nicht veröffentlicht hat, wie zum Beispiel PRoxies.
Wenn diese Dateien bei der Installation einer Komponente verwendet werden, können Sie diese Dateien umgehen und das Paket verwenden, das sie enthält.
In diesem Beispiel verwendet der Eigenschafteneditor die DesignEditors-Datei und die Proxies-Datei ist in DesignEditors erforderlich, sodass diese Komponente veröffentlicht wird
Das Paket (.dpk) enthält Designide, das das Problem löst, dass keine Proxys vorhanden sind, sodass die Komponenteninstallation erfolgreich ist.
Paket dsDlgPack;
...
erfordert
RTL,
vcl,
VclSmp,
designide;
enthält
dsDlgWaitEx in 'dsDlgWaitEx.pas' {DlgWaitEx},
dsDlgWaitExReg in 'dsDlgWaitExReg.pas';
Ende.
(3) Komponentenregistrierungsdatei dsDlgWaitExReg.pas
Frage: Warum müssen wir eine solche Datei häufiger verwenden?
Wenn der Code in dsDlgWaitExReg.pas in dsDlgWaitEx.pas zusammengeführt wird, obwohl Designide in dsDlgPack.dpk enthalten ist
Das Problem, dass bei der Installation der Komponente keine Proxys vorhanden waren, wurde behoben. Das Problem, dass keine Proxys vorhanden waren, tritt jedoch weiterhin auf, wenn die Anwendung diese Komponente aufruft.
Da in DesignEditors Proxies-Dateien benötigt werden, wird der folgende Code in einer separaten Datei zusammengefasst und die Anwendung ruft diese Gruppe auf
Die Datei muss dsDlgWaitExReg.pas nicht verwenden und kann Proxies problemlos umgehen.
Einheit dsDlgWaitExReg;
Schnittstelle
verwendet Klassen, Dialoge, Formulare, dsDlgWaitEx, DesignIntf, DesignEditors;
Typ
TdsAVIFileNameProperty = class(TStringProperty) //Der Eigenschafteneditor verwendet die DesignEditors-Datei
öffentlich
function GetAttributes:TPropertyAttributes;override; //Methodenüberschreibung
procedure Edit;override; //Methodenüberschreibung
Ende;
Verfahren Registrieren;
Durchführung
Verfahren Registrieren;
beginnen
//Registrieren Sie diese Komponente auf der Delisoft-Komponentenseite
RegisterComponents('Delisoft', [TdsWaitDialogEx]);
//Diesen Eigenschaftseditor registrieren
RegisterPropertyEditor(TypeInfo(string), TdsAVISource, 'FileName', TdsAVIFileNameProperty);
Ende;
{TdsAVIFileNameProperty}
Funktion TdsAVIFileNameProperty.GetAttributes:TPropertyAttributes;
beginnen
result:=[paDialog];
Ende;
Prozedur TdsAVIFileNameProperty.Edit;
beginnen
mit TOpenDialog.Create(application) tun
versuchen
Filter:='AVI-Dateien(*.avi)|*.avi|Alle Dateien(*.*)|*.*';
wenn Execute then SetStrValue(FileName);
Endlich
frei;
Ende;
Ende;
Ende.
(4) Komponentendatei dsDlgWaitEx.pas
Einheit dsDlgWaitEx;
{Definieren Sie alle Eigenschaften und Methoden dieser Komponente; darunter ist die Eigenschaft BorderStyle der Form TDlgWaitEx. In diesem Beispiel verwendet die Komponente TdsDlgWaitEx die Form TDlgWaitEx; das Eigenschaftsobjekt AVISource wird direkt von TPersistent geerbt Es werden Aufzählungseigenschaften (DialogStyle, AVIPosition) und Datensatzeigenschaften (Optionen) usw. verwendet.
}
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Varianten, Klassen, Grafiken, Steuerelemente, Formulare,
Dialoge, StdCtrls, Gauges, ComCtrls;
Typ
TDialogStyle = (dlgNormal, dlgStayOnTop);
TAVIPosition = (aviLeft, aviTop, aviBottom);
TDlgOptions = set of (showAVI,showCaption,showMessage1,showMessage2,showProgress,ShowProgressText);
TDlgWaitEx = class(TForm)
Animate1: TAnimate;
Gauge1: TGauge;
Label1: TLabel;
Label2: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
Privat
FCloseAfter: DWord;
FUserFormClose: TCloseEvent;
öffentlich
Eigenschaft UserFormClose: TCloseEvent read FUserFormClose write FUserFormClose;
Eigenschaft CloseAfter: DWORD read FCloseAfter write FCloseAfter;
Ende;
TdsAVISource = class(TPersistent)
Privat
FCommonAVI: TCommonAVI;
FFileName: string;
procedure SetCommonAVI(const Value: TCommonAVI);
procedure SetFileName(const Value: string);
geschützt
öffentlich
veröffentlicht
Eigenschaft CommonAVI: TCommonAVI lesen FCommonAVI schreiben SetCommonAVI Standard aviNone;
Eigenschaft FileName: string read FfileName write SetFileName;
Ende;
TdsWaitDialogEx=class(TComponent)
Privat
//Bilden
FDlgForm:TDlgWaitEx;
FMessage1: Zeichenfolge;
FMessage2: Zeichenfolge;
FMessage1Font:TFont;
FMessage2Font:TFont;
FCaption: string;
FDislogStyle:TDialogStyle;
FwordWrap:boolean;
FOptions:TDlgOptions;
FShowMessage1,FShowMessage2:boolean;
//AVI
FaviPosition: TAVIPosition;
FAviActive:boolean;
FshowAVI:boolean;
FAVISource: TdsAVISource;
//Fortschritt
FProgressMax:integer;
FProgressMin:integer;
FProgressPos:integer;
FProgressStep:integer;
FShowProgress: Boolean;
FShowProgressText: Boolean;
//Ereignis
FOnPosChange: TNotifyEvent;
FOnShow: TNotifyEvent;
FOnFormHide: TCloseEvent;
procedure SetProgressMax(const Value: integer);
procedure SetProgressMin(const Value: integer);
procedure SetProgressPos(const Value: integer);
procedure SetProgressStep(const Value: integer);
Prozedur DrawForm;
Funktion setLableHeight(sCaption:string):integer;
procedure setOptions(const value:TDlgOptions);
Prozedur setMessage1(const value:string);
Prozedur setMessage2(const value:string);
procedure setCaption(const value:string);
procedure SetMessage1Font(const value:TFont);
procedure SetMessage2Font(const value:TFont);
Funktion IsMessage1FontStored: Boolean;
Funktion IsMessage2FontStored: Boolean;
procedure setAVIPosition(const Value: TAVIPosition);
procedure SetAVISource(const Value: TdsAVISource);
procedure SetOnFormHide(const Value: TCloseEvent);
geschützt
Prozedur DoPosChange; virtuell;
Prozedur DoShow; virtuell;
öffentlich
Konstruktor Create(AOwner: TComponent);
Destruktor Zerstören; überschreiben;
Prozedur FormShow;
Prozedur FormHide;
Prozedur FormUpdate;
Prozedur ProgressStepIt;
veröffentlicht
//Bilden
Eigenschaft Message1: String read FMessage1 write setMessage1;
Eigenschaft Message2: String read FMessage2 write setMessage2;
Eigenschaft Message1Font: TFont lesen FMessage1Font schreiben SetMessage1Font gespeichert IsMessage1FontStored;
Eigenschaft Message2Font: TFont lesen FMessage2Font schreiben SetMessage2Font gespeichert IsMessage2FontStored;
Eigenschaft Caption: string read FCaption write setCaption;
Eigenschaft DislogStyle:TDialogStyle read FDislogStyle write FDislogStyle;
Eigenschaft wordWrap :boolean read FwordWrap write FwordWrap;
Eigenschaft Optionen:TDlgOptions lesen FOptions schreiben setOptions;
//AVI
Eigenschaft AviActive: boolean read FAviActive write FAviActive;
Eigenschaft AviPosition: TAVIPosition lesen FaviPosition schreiben setAVIPosition;
Eigenschaft AviSource: TdsAVISource read FAVISource write SetAVISource;
//Fortschritt
Eigenschaft ProgressMax: Ganzzahl lesen FProgressMax schreiben SetProgressMax;
Eigenschaft ProgressMin: Ganzzahl lesen FProgressMin schreiben SetProgressMin;
Eigenschaft ProgressPos: Ganzzahl lesen FProgressPos schreiben SetProgressPos;
property ProgressStep:integer read FProgressStep write SetProgressStep;
//Ereignis
Eigenschaft OnPosChange: TNotifyEvent read FOnPosChange write FOnPosChange;
Eigenschaft OnShow: TNotifyEvent read FOnShow write FOnShow;
Eigenschaft OnHide: TCloseEvent read FOnFormHide write SetOnFormHide;
Ende;
Durchführung
{$R *.DFM}
{TdsAVISource}
procedure TdsAVISource.SetCommonAVI(const Value: TCommonAVI);
beginnen
wenn Value = FCommonAVI, dann beenden;
FCommonAVI := Wert;
FfileName:='';
Ende;
procedure TdsAVISource.SetFileName(const Value: string);
beginnen
wenn Value = FfileName, dann beenden;
FfileName:=value;
FCommonAVI:=aviNone;
Ende;
{TdsWaitDialogEx}
procedure TdsWaitDialogEx.DoShow;
beginnen
if Assigned(FOnShow) then FOnShow(Self);
Ende;
procedure TdsWaitDialogEx.DoPosChange;
beginnen
if Assigned(FOnPosChange) then FOnPosChange(Self);
Ende;
procedure TdsWaitDialogEx.SetAVISource(const Value: TdsAVISource);
beginnen
wenn FAVISource=value dann beenden;
FAVISource.Assign(Value);
if (FAVISource.FFileName='')and(FAVISource.FCommonAVI=aviNone) then FshowAVI:=false;
wenn zugewiesen(FDlgForm), dann
beginnen
FDlgForm.Animate1.Active:=false;
FDlgForm.Animate1.FileName := '';
FDlgForm.Animate1.CommonAVI := aviNone;
wenn FshowAVI dann
beginnen
if FAVISource.FfileName='' dann
FDlgForm.Animate1.CommonAVI := FAVISource.FCommonAVI
anders
FDlgForm.Animate1.FileName := FAVISource.FfileName;
FDlgForm.Animate1.Active:=true;
Ende;
DrawForm; //Animate1->Nach AVI-Änderungen kann sich die Größe von Animate1 ändern ==> DrawForm
FDlgForm.Update;
Ende;
Ende;
Funktion TdsWaitDialogEx.IsMessage1FontStored: Boolean;
beginnen
mit FMessage1Font tun
Ergebnis :=
(Name <> 'MS Sans Serif') oder
(Stil <> []) oder
(Größe <> 8) oder
(Farbe <> clWindowText) oder
(Charset <> DEFAULT_CHARSET) oder
(Pitch <> fpDefault);
Ende;
Funktion TdsWaitDialogEx.IsMessage2FontStored: Boolean;
beginnen
mit FMessage2Font tun
Ergebnis :=
(Name <> 'MS Sans Serif') oder
(Stil <> []) oder
(Größe <> 8) oder
(Farbe <> clWindowText) oder
(Charset <> DEFAULT_CHARSET) oder
(Pitch <> fpDefault);
Ende;
procedure TdsWaitDialogEx.SetMessage1Font(const Value: TFont);
beginnen
FMessage1Font.Assign(Value);
wenn zugewiesen(FDlgForm), dann
beginnen
FDlgForm.Label1.Font.Assign(Value);
FDlgForm.Update;
Ende;
Ende;
procedure TdsWaitDialogEx.SetMessage2Font(const Value: TFont);
beginnen
FMessage2Font.Assign(Value);
wenn zugewiesen(FDlgForm), dann
beginnen
FDlgForm.Label2.Font.Assign(Value);
FDlgForm.Update;
Ende;
Ende;
procedure TdsWaitDialogEx.setCaption(const value:string);
beginnen
wenn value=FCaption, dann beenden;
FCaption:=value;
Wenn nicht (showCaption in FOptions), dann
beginnen
FCaption:='';
Ausfahrt;
Ende;
wenn zugewiesen(FDlgForm), dann
beginnen
FDlgForm.Caption := value;
FDlgForm.update;
Ende;
Ende;
procedure TdsWaitDialogEx.setMessage1(const value:string);
var i:integer;
beginnen
wenn value=FMessage1 dann beenden;
FMessage1:=Wert;
wenn zugewiesen(FDlgForm), dann
beginnen
wenn nicht (showMessage1 in FOptions), dann beenden;
FDlgForm.Label1.Caption := value;
i:=setLableHeight(FMessage1)+13;
if i<>FDlgForm.Label1.Height then DrawForm;
FDlgForm.update;
Ende;
Ende;
procedure TdsWaitDialogEx.setMessage2(const value:string);
var i:integer;
beginnen
wenn value=FMessage2, dann beenden;
FMessage2:=Wert;
wenn zugewiesen(FDlgForm), dann
beginnen
Wenn nicht (showMessage2 in FOptions), dann beenden;
FDlgForm.Label2.Caption := value;
i:=setLableHeight(FMessage2)+13;
if i<>FDlgForm.Label2.Height then DrawForm;
FDlgForm.update;
Ende;
Ende;