Editeur de composants et de propriétés Delphi
(1) Préface
Cet article utilisera un exemple pour décrire le développement de composants et l'éditeur de propriétés.
L'exemple (TdsWaitDialogEx) est un composant visuel qui affiche un Dialog après avoir appelé sa méthode show.
Il contient un TAnimate, deux messages d'invite (c'est-à-dire TLabel) et une barre de progression (TGauge).
Propriétés d'énumération : DialogStyle, AViposition
Propriétés de l'enregistrement : options
L'objet de collection de propriétés hérite de TPersistent. Dans cet exemple, la collection de propriétés AVISource contient TAnimate.
Propriétés de l'animation CommonAVI, FileName
L'éditeur de propriétés est appliqué avec la propriété FileName de AVISource, c'est-à-dire qu'un String FileName apparaît lors de l'édition.
TOpenDialog, son filtre de filtrage est *.avi
(2) Package de composants dsDlgPack.dpk
Afin de faciliter la publication, l'installation, etc., le package de composants .dpk doit être utilisé.
Dans les versions postérieures à Delphi6 (je ne connais pas les versions antérieures à D5), il existe plusieurs fichiers que Delphi n'a pas publiés, comme les PRoxyes.
Si ces fichiers sont utilisés lors de l'installation d'un composant, vous pouvez contourner ces fichiers et utiliser le package qui les contient.
Dans cet exemple, l'éditeur de propriétés utilise le fichier DesignEditors et le fichier Proxies est requis dans DesignEditors, ce composant est donc publié
Le package (.dpk) contient designide, qui résout le problème de l'absence de proxy, afin que l'installation du composant réussisse.
paquet dsDlgPack ;
...
nécessite
rtl,
vcl,
VclSmp,
designide;
contient
dsDlgWaitEx dans 'dsDlgWaitEx.pas' {DlgWaitEx},
dsDlgWaitExReg dans 'dsDlgWaitExReg.pas' ;
fin.
(3) Fichier d'enregistrement des composants dsDlgWaitExReg.pas
Question : Pourquoi devons-nous utiliser un tel fichier plus souvent ? Parce que :
Si le code dans dsDlgWaitExReg.pas est fusionné dans dsDlgWaitEx.pas, bien que designide soit inclus dans dsDlgPack.dpk
Résolution du problème des proxys inexistants lors de l'installation du composant, mais le problème des proxys inexistants se produit toujours lorsque l'application appelle ce composant.
Étant donné que les fichiers proxy sont nécessaires dans DesignEditors, le code suivant est formé dans un fichier distinct et l'application appelle ce groupe ;
Le fichier n'a pas besoin d'utiliser dsDlgWaitExReg.pas et peut contourner les proxys sans aucun problème.
unité dsDlgWaitExReg ;
interface
utilise des classes, des boîtes de dialogue, des formulaires, dsDlgWaitEx, DesignIntf, DesignEditors ;
taper
TdsAVIFileNameProperty = class(TStringProperty) //L'éditeur de propriétés utilise le fichier DesignEditors
publique
function GetAttributes:TPropertyAttributes;override; //Remplacement de la méthode
procédure Edit;override; //remplacement de méthode
fin;
registre de procédure ;
mise en œuvre
registre de procédure ;
commencer
//Enregistrez ce composant sur la page du composant Delisoft
RegisterComponents('Delisoft', [TdsWaitDialogEx]);
//Enregistrer cet éditeur de propriétés
RegisterPropertyEditor(TypeInfo(string), TdsAVISource, 'FileName', TdsAVIFileNameProperty);
fin;
{TdsAVIFileNameProperty}
fonction TdsAVIFileNameProperty.GetAttributes:TPropertyAttributes;
commencer
résultat :=[paDialog] ;
fin;
procédure TdsAVIFileNameProperty.Edit;
commencer
avec TOpenDialog.Create(application) faire
essayer
Filtre :='Fichiers AVI(*.avi)|*.avi|Tous les fichiers(*.*)|*.*';
si Exécuter, alors SetStrValue(FileName);
enfin
gratuit;
fin;
fin;
fin.
(4) Fichier de composant dsDlgWaitEx.pas
unité dsDlgWaitEx ;
{Définissez toutes les propriétés et méthodes de ce composant ; parmi elles, la propriété BorderStyle du formulaire TDlgWaitEx est bsDialog. Dans cet exemple, le composant TdsDlgWaitEx utilise le formulaire TDlgWaitEx ; l'objet de propriété AVISource utilise TdsAVISource, qui est directement hérité de TPersistent, et les propriétés d'énumération sont utilisées (DialogStyle, AVIPosition) et les propriétés d'enregistrement (Options), etc.
}
interface
utilise
Windows, messages, SysUtils, variantes, classes, graphiques, contrôles, formulaires,
Boîtes de dialogue, StdCtrls, Jauges, ComCtrls ;
taper
TDialogStyle = (dlgNormal, dlgStayOnTop);
TAVIPosition = (aviLeft, aviTop, aviBottom);
TDlgOptions = ensemble de (showAVI,showCaption,showMessage1,showMessage2,showProgress,ShowProgressText) ;
TDlgWaitEx = classe (TForm)
Animer1 : TAnimate ;
Jauge1 : TGauge ;
Étiquette1 : TLabel ;
Étiquette2 : TLabel ;
procédure FormClose (Expéditeur : TObject ; var Action : TCloseAction);
privé
FCloseAfter : DWord ;
FUserFormClose : TCloseEvent ;
publique
propriété UserFormClose : TCloseEvent lire FUserFormClose écrire FUserFormClose ;
propriété CloseAfter : DWORD lit FCloseAfter écrit FCloseAfter ;
fin;
TdsAVISource = classe (TPersistent)
privé
FCommonAVI : TCommonAVI ;
FFileName : chaîne ;
procédure SetCommonAVI(valeur const : TCommonAVI);
procédure SetFileName (const Value : string);
protégé
publique
publié
propriété CommonAVI : TCommonAVI lit FCommonAVI écrit SetCommonAVI par défaut aviNone ;
propriété FileName : chaîne lue FfileName écriture SetFileName ;
fin;
TdsWaitDialogEx=classe(TComponent)
privé
//Formulaire
FDlgForm:TDlgWaitEx;
FMessage1 : chaîne ;
FMessage2 : chaîne ;
FMessage1Font:TFont;
FMessage2Font:TFont;
FCaption : chaîne ;
FDislogStyle:TDialogStyle;
FwordWrap:booléen;
FOptions : TDlgOptions ;
FShowMessage1,FShowMessage2:booléen;
//AVI
Position Favi : TAVIPosition ;
FAviActive:booléen;
FshowAVI:booléen;
FAVISource : TdsAVISource;
//progrès
FProgressMax:entier;
FProgressMin:entier;
FProgressPos : entier ;
FProgressStep:entier;
FShowProgress : booléen ;
FShowProgressText : booléen ;
//Événement
FOnPosChange : TNotifyEvent ;
FOnShow : TNotifyEvent ;
FOnFormHide : TCloseEvent ;
procédure SetProgressMax (const Value : entier);
procédure SetProgressMin (valeur const : entier);
procédure SetProgressPos (const Value : entier);
procédure SetProgressStep (valeur const : entier);
procédure DrawForm;
fonction setLableHeight(sCaption:string):integer;
procédure setOptions (valeur const: TDlgOptions);
procédure setMessage1 (valeur const: chaîne);
procédure setMessage2 (valeur const: chaîne);
procédure setCaption (valeur const: chaîne);
procédure SetMessage1Font (valeur const: TFont);
procédure SetMessage2Font (valeur const: TFont);
fonction IsMessage1FontStored : booléen ;
fonction IsMessage2FontStored : booléen ;
procédure setAVIPosition (valeur const : TAVIPosition);
procédure SetAVISource (valeur const : TdsAVISource);
procédure SetOnFormHide(const Value: TCloseEvent);
protégé
procédure DoPosChange ; virtuel ;
procédure DoShow; virtuel;
publique
constructeur Create (AOwner : TComponent );
destructeur Détruire ;
procédure FormShow ;
procédure FormHide ;
procédure FormUpdate;
procédure ProgressStepIt ;
publié
//Formulaire
propriété Message1 : chaîne lue FMessage1 écriture setMessage1 ;
propriété Message2 : chaîne lue FMessage2 écriture setMessage2 ;
propriété Message1Font : TFont lit FMessage1Font écriture SetMessage1Font stocké IsMessage1FontStored ;
propriété Message2Font : TFont lit FMessage2Font écriture SetMessage2Font stocké IsMessage2FontStored ;
property Caption : string read FCaption write setCaption ;
propriété DislogStyle:TDialogStyle lire FDislogStyle écrire FDislogStyle ;
propriété wordWrap :boolean read FwordWrap write FwordWrap ;
Propriété Options : TDlgOptions lire FOptions écrire setOptions ;
//AVI
propriété AviActive : booléen lecture FAviActive écriture FAviActive ;
propriété AviPosition : TAVIPosition lecture FaviPosition écriture setAVIPosition ;
propriété AviSource : TdsAVISource lecture FAVISource écriture SetAVISource ;
//Progrès
propriété ProgressMax : entier lire FProgressMax écrire SetProgressMax ;
propriété ProgressMin : entier lire FProgressMin écrire SetProgressMin ;
propriété ProgressPos : entier lu FProgressPos écriture SetProgressPos ;
propriété ProgressStep : entier lire FProgressStep écrire SetProgressStep ;
//Événement
propriété OnPosChange : TNotifyEvent lecture FOnPosChange écriture FOnPosChange ;
propriété OnShow : TNotifyEvent lecture FOnShow écriture FOnShow ;
propriété OnHide : TCloseEvent lecture FOnFormHide écriture SetOnFormHide ;
fin;
mise en œuvre
{$R *.DFM}
{TdsAVISource}
procédure TdsAVISource.SetCommonAVI(const Value: TCommonAVI);
commencer
si Value = FCommonAVI alors quittez ;
FCommonAVI := Valeur ;
FfileName:='';
fin;
procédure TdsAVISource.SetFileName(const Value: string);
commencer
si Value = FfileName alors quittez ;
FfileName:=valeur ;
FCommonAVI:=aviNone;
fin;
{TdsWaitDialogEx}
procédure TdsWaitDialogEx.DoShow ;
commencer
si assigné (FOnShow) alors FOnShow (Self);
fin;
procédure TdsWaitDialogEx.DoPosChange ;
commencer
si assigné (FOnPosChange) alors FOnPosChange (Self);
fin;
procédure TdsWaitDialogEx.SetAVISource (valeur const : TdsAVISource);
commencer
si FAVISource=value alors quittez ;
FAVISource.Assign(Valeur);
if (FAVISource.FFileName='')et(FAVISource.FCommonAVI=aviNone) alors FshowAVI:=false;
si attribué (FDlgForm) alors
commencer
FDlgForm.Animate1.Active:=false;
FDlgForm.Animate1.FileName := '';
FDlgForm.Animate1.CommonAVI := aviNone;
si FshowAVI alors
commencer
si FAVISource.FfileName='' alors
FDlgForm.Animate1.CommonAVI := FAVISource.FCommonAVI
autre
FDlgForm.Animate1.FileName := FAVISource.FfileName;
FDlgForm.Animate1.Active:=true;
fin;
DrawForm; //Animate1->Après les modifications d'AVI, la taille d'Animate1 peut changer ==> DrawForm
FDlgForm.Update ;
fin;
fin;
fonction TdsWaitDialogEx.IsMessage1FontStored : booléen ;
commencer
avec FMessage1Font faire
Résultat :=
(Nom <> 'MS Sans Serif') ou
(Style <> []) ou
(Taille <> 8) ou
(Couleur <> clWindowText) ou
(Charset <> DEFAULT_CHARSET) ou
(Pas <> fpDefault);
fin;
fonction TdsWaitDialogEx.IsMessage2FontStored : booléen ;
commencer
avec FMessage2Font faire
Résultat :=
(Nom <> 'MS Sans Serif') ou
(Style <> []) ou
(Taille <> 8) ou
(Couleur <> clWindowText) ou
(Charset <> DEFAULT_CHARSET) ou
(Pas <> fpDefault);
fin;
procédure TdsWaitDialogEx.SetMessage1Font (valeur const : TFont);
commencer
FMessage1Font.Assign(Valeur);
si attribué (FDlgForm) alors
commencer
FDlgForm.Label1.Font.Assign(Valeur);
FDlgForm.Update ;
fin;
fin;
procédure TdsWaitDialogEx.SetMessage2Font (valeur const : TFont);
commencer
FMessage2Font.Assign(Valeur);
si attribué (FDlgForm) alors
commencer
FDlgForm.Label2.Font.Assign(Valeur);
FDlgForm.Update ;
fin;
fin;
procédure TdsWaitDialogEx.setCaption(const value:string);
commencer
si valeur = FCaption alors quittez ;
FCaption :=valeur ;
sinon (showCaption dans FOptions) alors
commencer
FCaption:='';
sortie;
fin;
si attribué (FDlgForm) alors
commencer
FDlgForm.Caption := valeur ;
FDlgForm.update;
fin;
fin;
procédure TdsWaitDialogEx.setMessage1(const value:string);
var je:entier;
commencer
si valeur = FMessage1 alors quittez ;
FMessage1 :=valeur ;
si attribué (FDlgForm) alors
commencer
sinon (showMessage1 dans FOptions), alors quittez ;
FDlgForm.Label1.Caption := valeur ;
je:=setLableHeight(FMessage1)+13;
si i<>FDlgForm.Label1.Height alors DrawForm ;
FDlgForm.update;
fin;
fin;
procédure TdsWaitDialogEx.setMessage2(const value:string);
var je:entier;
commencer
si valeur = FMessage2 alors quittez ;
FMessage2 :=valeur ;
si attribué (FDlgForm) alors
commencer
sinon (showMessage2 dans FOptions), alors quittez ;
FDlgForm.Label2.Caption := valeur ;
je:=setLableHeight(FMessage2)+13;
si i<>FDlgForm.Label2.Height alors DrawForm ;
FDlgForm.update;
fin;
fin;