Editor de propiedades y componentes de Delphi
(1) Prefacio
Este artículo utilizará un ejemplo para describir el desarrollo de componentes y el editor de propiedades.
El ejemplo (TdsWaitDialogEx) es un componente visual que muestra un cuadro de diálogo después de llamar a su método show.
Contiene un TAnimate, dos mensajes de aviso (es decir, TLabel) y una barra de progreso (TGauge).
Propiedades de enumeración: DialogStyle, AViposition
Propiedades de registro: Opciones
El objeto de colección de propiedades hereda de TPersistent. En este ejemplo, la colección de propiedades AVISource contiene TAnimate.
Propiedades de animación CommonAVI, FileName
El editor de propiedades se aplica con la propiedad FileName de AVISource, es decir, aparece un String FileName al editar.
TOpenDialog, su filtro de filtrado es *.avi
(2) Paquete de componentes dsDlgPack.dpk
Para facilitar la publicación, instalación, etc., se debe utilizar el paquete de componentes .dpk.
En versiones posteriores a Delphi6 (no sé de versiones anteriores a D5), hay varios archivos que Delphi no ha publicado, como por ejemplo PRoxies.
Si estos archivos se utilizan al instalar un componente, puede omitirlos y utilizar el paquete que los contiene.
En este ejemplo, el editor de propiedades utiliza el archivo DesignEditors y el archivo Proxies es necesario en DesignEditors, por lo que este componente se publica.
El paquete (.dpk) contiene designide, que soluciona el problema de que los Proxies no existen, para que la instalación del componente sea exitosa.
paquete dsDlgPack;
...
requiere
rtl,
vcl,
VclSmp,
designar;
contiene
dsDlgWaitEx en 'dsDlgWaitEx.pas' {DlgWaitEx},
dsDlgWaitExReg en 'dsDlgWaitExReg.pas';
fin.
(3) Archivo de registro de componentes dsDlgWaitExReg.pas
Pregunta: ¿Por qué necesitamos utilizar un archivo de este tipo con más frecuencia? Porque:
Si el código en dsDlgWaitExReg.pas se fusiona en dsDlgWaitEx.pas, aunque designide se incluye en dsDlgPack.dpk
Se resolvió el problema de que los Proxies no existían al instalar el componente, pero el problema de los Proxies que no existían aún ocurre cuando la aplicación llama a este componente.
Debido a que los archivos Proxies son necesarios en DesignEditors, el siguiente código se forma en un archivo separado y la aplicación llama a este grupo;
El archivo no necesita utilizar dsDlgWaitExReg.pas y puede omitir Proxies sin ningún problema.
unidad dsDlgWaitExReg;
interfaz
utiliza Clases, Diálogos, Formularios, dsDlgWaitEx, DesignIntf, DesignEditors;
tipo
TdsAVIFileNameProperty = class(TStringProperty) //El editor de propiedades utiliza el archivo DesignEditors
público
función GetAttributes:TPropertyAttributes;override; //Anulación del método
procedimiento Editar; anular; // anular el método
fin;
Registro de trámites;
implementación
Registro de trámites;
comenzar
//Registra este componente en la página del componente Delisoft
RegisterComponents('Delisoft', [TdsWaitDialogEx]);
//Registrar este editor de propiedades
RegisterPropertyEditor(TypeInfo(cadena), TdsAVISource, 'FileName', TdsAVIFileNameProperty);
fin;
{TdsAVIFileNameProperty}
función TdsAVIFileNameProperty.GetAttributes:TPropertyAttributes;
comenzar
resultado:=[paDialog];
fin;
procedimiento TdsAVIFileNameProperty.Edit;
comenzar
con TOpenDialog.Create(aplicación) hacer
intentar
Filtro:='Archivos AVI(*.avi)|*.avi|Todos los archivos(*.*)|*.*';
si se ejecuta, entonces SetStrValue(FileName);
finalmente
gratis;
fin;
fin;
fin.
(4) Archivo componente dsDlgWaitEx.pas
unidad dsDlgWaitEx;
{Defina todas las propiedades y métodos de este componente; entre ellos, la propiedad BorderStyle del formulario TDlgWaitEx es bsDialog. En este ejemplo, el componente TdsDlgWaitEx usa el formulario TDlgWaitEx y el objeto de propiedad AVISource usa TdsAVISource, que se hereda directamente de TPersistent; Se utilizan propiedades de enumeración (DialogStyle, AVIPOsition) y propiedades de registro (Opciones), etc.
}
interfaz
usos
Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos, Controles, Formularios,
Diálogos, StdCtrls, Indicadores, ComCtrls;
tipo
TDialogStyle = (dlgNormal, dlgStayOnTop);
TAVIPosition = (aviIzquierda, aviArriba, aviAbajo);
TDlgOptions = conjunto de (showAVI,showCaption,showMessage1,showMessage2,showProgress,ShowProgressText);
TDlgWaitEx = clase(TForm)
Animar1: TAnimar;
Calibre 1: calibre T;
Etiqueta1: TLabel;
Etiqueta2: TLabel;
procedimiento FormClose(Remitente: TObject; var Acción: TCloseAction);
privado
FCoseAfter: DWord;
FUserFormClose: TCloseEvent;
público
propiedad UserFormClose: TCloseEvent lee FUserFormClose escribe FUserFormClose;
propiedad CloseAfter: DWORD leer FCloseAfter escribir FCloseAfter;
fin;
TdsAVISource = clase(TPersistente)
privado
FCommonAVI: TCommonAVI;
FFileName: cadena;
procedimiento SetCommonAVI (valor constante: TCommonAVI);
procedimiento SetFileName (valor constante: cadena);
protegido
público
publicado
propiedad CommonAVI: TCommonAVI lee FCommonAVI escribe SetCommonAVI predeterminado aviNone;
propiedad FileName: cadena lee FfileName escribe SetFileName;
fin;
TdsWaitDialogEx=clase(TComponent)
privado
//Forma
FDlgForm:TDlgWaitEx;
FMessage1: cadena;
FMessage2: cadena;
FMessage1Fuente:TFont;
FMessage2Fuente:TFont;
FCaption: cadena;
FDislogStyle:TDialogStyle;
FwordWrap: booleano;
OpcionesF:TDlgOptions;
FShowMessage1,FShowMessage2:booleano;
//AVI
Posición Favi: Posición TAVI;
FAviActive:booleano;
FshowAVI:booleano;
Fuente FAVI: Fuente TdsAVI;
//progreso
FProgressMax: entero;
FProgressMin:entero;
FProgressPos: entero;
FProgressStep: entero;
FShowProgress: booleano;
FShowProgressText: booleano;
//Evento
FOnPosChange: TNotifyEvent;
FOnShow: TNotifyEvent;
FOnFormHide: TCloseEvent;
procedimiento SetProgressMax(Valor constante: entero);
procedimiento SetProgressMin(Valor constante: entero);
procedimiento SetProgressPos(Valor constante: entero);
procedimiento SetProgressStep(Valor constante: entero);
procedimiento DrawForm;
función setLableHeight(sCaption:string):integer;
procedimiento setOptions (valor constante: TDlgOptions);
procedimiento setMessage1 (valor constante: cadena);
procedimiento setMessage2 (valor constante: cadena);
procedimiento setCaption (valor constante: cadena);
procedimiento SetMessage1Font (valor constante: TFont);
procedimiento SetMessage2Font (valor constante: TFont);
función IsMessage1FontStored: booleana;
función IsMessage2FontStored: booleana;
procedimiento setAVIPosition(Valor constante: TAVIPosition);
procedimiento SetAVISource(Valor constante: TdsAVISource);
procedimiento SetOnFormHide (valor constante: TCloseEvent);
protegido
procedimiento DoPosChange;
procedimiento DoShow virtual;
público
constructor Crear (AOwner: TComponent);
destructor Destruir; anular;
procedimiento FormShow;
procedimiento FormHide;
procedimiento FormUpdate;
procedimiento ProgressStepIt;
publicado
//Forma
propiedad Mensaje1: cadena lee FMessage1 escribe setMessage1;
propiedad Mensaje2: cadena leída FMessage2 escritura setMessage2;
propiedad Message1Font: TFont lee FMessage1Font escribe SetMessage1Font almacenado IsMessage1FontStored;
propiedad Message2Font: TFont lee FMessage2Font escribe SetMessage2Font almacenado IsMessage2FontStored;
propiedad Título: cadena leer FCaption escribir setCaption;
propiedad DislogStyle:TDialogStyle leer FDislogStyle escribir FDislogStyle;
propiedad wordWrap: booleano leer FwordWrap escribir FwordWrap;
Opciones de propiedad:TDlgOptions leer FOptions escribir setOptions;
//AVI
propiedad AviActive: lectura booleana FAviActive escritura FAviActive;
propiedad AviPosition: TAVIPosition leer FaviPosition escribir setAVIPosition;
propiedad AviSource: TdsAVISource leer FAVISource escribir SetAVISource;
//Progreso
propiedad ProgressMax: entero leído FProgressMax escribir SetProgressMax;
propiedad ProgressMin: entero leído FProgressMin escribir SetProgressMin;
propiedad ProgressPos: entero leído FProgressPos escribir SetProgressPos;
propiedad ProgressStep: entero leer FProgressStep escribir SetProgressStep;
//Evento
propiedad OnPosChange: TNotifyEvent lee FOnPosChange escribe FOnPosChange;
propiedad OnShow: TNotifyEvent lee FOnShow escribe FOnShow;
propiedad OnHide: TCloseEvent lee FOnFormHide escribe SetOnFormHide;
fin;
implementación
{$R *.DFM}
{TdsAVIFuente}
procedimiento TdsAVISource.SetCommonAVI (valor constante: TCommonAVI);
comenzar
si Valor = FCommonAVI entonces salga;
FCommonAVI := Valor;
NombreDeArchivo:='';
fin;
procedimiento TdsAVISource.SetFileName (valor constante: cadena);
comenzar
si Valor = FfileName entonces salga;
FfileName:=valor;
FCommonAVI:=aviNinguno;
fin;
{TdsWaitDialogEx}
procedimiento TdsWaitDialogEx.DoShow;
comenzar
si está asignado (FOnShow), entonces FOnShow (Self);
fin;
procedimiento TdsWaitDialogEx.DoPosChange;
comenzar
si está asignado (FOnPosChange), entonces FOnPosChange (Self);
fin;
procedimiento TdsWaitDialogEx.SetAVISource (Valor constante: TdsAVISource);
comenzar
si FAVISource=valor entonces salga;
FAVISource.Assign(Valor);
si (FAVISource.FFileName='')y(FAVISource.FCommonAVI=aviNone) entonces FshowAVI:=false;
si está asignado (FDlgForm) entonces
comenzar
FDlgForm.Animate1.Active:=falso;
FDlgForm.Animate1.FileName := '';
FDlgForm.Animate1.CommonAVI := aviNone;
si FshowAVI entonces
comenzar
si FAVISource.FfileName='' entonces
FDlgForm.Animate1.CommonAVI := FAVISource.FCommonAVI
demás
FDlgForm.Animate1.FileName := FAVISource.FfileName;
FDlgForm.Animate1.Active:=verdadero;
fin;
DrawForm; //Animate1->Después de los cambios de AVI, el tamaño de Animate1 puede cambiar ==> DrawForm
FDlgForm.Actualización;
fin;
fin;
función TdsWaitDialogEx.IsMessage1FontStored: booleano;
comenzar
con FMessage1Font hacer
Resultado :=
(Nombre <> 'MS Sans Serif') o
(Estilo <> []) o
(Tamaño <> 8) o
(Color <> clWindowText) o
(Juego de caracteres <> DEFAULT_CHARSET) o
(Tono <> fpDefault);
fin;
función TdsWaitDialogEx.IsMessage2FontStored: booleano;
comenzar
con FMessage2Font hacer
Resultado :=
(Nombre <> 'MS Sans Serif') o
(Estilo <> []) o
(Tamaño <> 8) o
(Color <> clWindowText) o
(Juego de caracteres <> DEFAULT_CHARSET) o
(Tono <> fpDefault);
fin;
procedimiento TdsWaitDialogEx.SetMessage1Font (Valor constante: TFont);
comenzar
FMessage1Font.Assign(Valor);
si está asignado (FDlgForm) entonces
comenzar
FDlgForm.Label1.Font.Assign(Valor);
FDlgForm.Actualización;
fin;
fin;
procedimiento TdsWaitDialogEx.SetMessage2Font (Valor constante: TFont);
comenzar
FMessage2Font.Assign(Valor);
si está asignado (FDlgForm) entonces
comenzar
FDlgForm.Label2.Font.Assign(Valor);
FDlgForm.Actualización;
fin;
fin;
procedimiento TdsWaitDialogEx.setCaption (valor constante: cadena);
comenzar
si valor=FCaption entonces salga;
FCaption:=valor;
si no (showCaption en FOptions) entonces
comenzar
FCaption:='';
salida;
fin;
si está asignado (FDlgForm) entonces
comenzar
FDlgForm.Caption: = valor;
FDlgForm.actualización;
fin;
fin;
procedimiento TdsWaitDialogEx.setMessage1 (valor constante: cadena);
var i: entero;
comenzar
si valor = FMessage1 entonces salga;
FMessage1:=valor;
si está asignado (FDlgForm) entonces
comenzar
si no (showMessage1 en FOptions), salga;
FDlgForm.Label1.Caption := valor;
i:=setLableHeight(FMessage1)+13;
si i<>FDlgForm.Label1.Height entonces DrawForm;
FDlgForm.actualización;
fin;
fin;
procedimiento TdsWaitDialogEx.setMessage2 (valor constante: cadena);
var i: entero;
comenzar
si valor = FMessage2 entonces salga;
FMessage2:=valor;
si está asignado (FDlgForm) entonces
comenzar
si no (showMessage2 en FOptions), salga;
FDlgForm.Label2.Caption: = valor;
i:=setLableHeight(FMessage2)+13;
si i<>FDlgForm.Label2.Height entonces DrawForm;
FDlgForm.actualización;
fin;
fin;