Declaración con Máscaras:
En esta declaración la parte de lectura (read) de la propiedad se cambia por una función. (El nombre de la función puede ser cualquiera, por convención es GET + nombre de la propiedad). Luego de escribir
property Color: Integer read GetColor write fColor;
presionamos Ctrl + Shift + C y Delphi crea una variable privada fColor del tipo Integer y un procedimiento privado GetColor más el cuerpo del mismo.
function TOpciones.GetColor: Integer;
begin
Result := ABS(fColor); //Es equivalente a GetColor := ABS(fColor);
end;
Dentro de la función debemos asignar al resultado de la función (usando el nombre o “result”) el valor que está almacenado.
¿Cómo funciona?
Cuando escribimos… el compilador lo traduce en …
Opciones.Color := Panel1.Color; Opciones.FColor := Panel1.Color;
Label1.Color := Opciones.Color; Label1.Color := Opciones.GetColor;
¿Cómo se guardan las propiedades? Sólo se guardarán las propiedades declaradas en la sección published. Las propiedades publicadas de tipo Integer, Char, Boolean, Real, String, TFont, TStrings, TDateTime y sus símiles (TColor, Byte, AnsiString, WideBool, etc), se almacenan sin inconvenientes y no requieren de nuestra intervención. En cambio, las propiedades de tipo TPoint, TRect (y la mayoría de los descendientes de TObject) necesitan que les indiquemos cómo deben guardarse. Para esto debemos seguir los siguientes pasos:
Paso 1 En la sección protected debemos agregar:
procedure DefineProperties(Filer: TFiler); override;
En el cuerpo del procedimiento indicamos cómo se guardarán y leerán los valores
procedure TOpciones.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('ARECT', ReadRect, WriteRect, True);
end;
El primer parámetro es el nombre con que se guarda la propiedad en el objeto, ReadRect y WriteRect son procedimientos privados o protegidos de nuestra clase. El último parámetro lo dejamos en verdadero.
Paso 2 Declaramos (en private o protected) los procedimientos de lectura y escritura:
procedure ReadRect(Reader:Treader);
procedure WriteRect(Writer:Twriter);
(Si presionamos Ctrl + Shift + C, Delphi completa las declaraciones)
Paso 3 Implementamos los procedimientos:
procedure TOpciones.WriteRect(Writer: Twriter);
begin
Writer.WriteListBegin;
Writer.WriteInteger(FARect.Left);
Writer.WriteInteger(FARect.Top);
Writer.WriteInteger(FARect.Right);
Writer.WriteInteger(FARect.Bottom);
Writer.WriteListEnd;
end;
procedure TOpciones.ReadRect(Reader: Treader);
begin
Reader.ReadListBegin;
FARect.Left := Reader.ReadInteger;
FARect.Top := Reader.ReadInteger;
FARect.Right := Reader.ReadInteger;
FARect.Bottom := Reader.ReadInteger;
Reader.ReadListEnd;
end;
En estos procedimientos conviene siempre hacer referencia a las variables privadas en lugar de hacer referencia a las propiedades.
Propiedades que son objetos:
Debemos sobrescribir el constructor para Crear nuestros objetos internos (Font, Lines y otros) e inicializar las variables internas. La declaración será (en la sección public)
constructor Create(aOwner: TComponent); override;
y el cuerpo …
constructor TOpciones.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
fLines := TStringList.Create; //Nunca usar fLines:= TStrings.Create;
fFont := TFont.Create;
fLastUse := Now;
fColor := 65535; //clYellow
//...
end;
Todo lo que hemos creamos, debemos destruirlo
destructor TOpciones.Destroy;
begin
//...
fLines.Free;
fFont.Free;
inherited Destroy;
//...
end;
El corazón de la bestia. Leyendo y guardando el objeto Nuestro componente hereda de TComponent por estos motivos:
Para guardar y leer nos valemos de dos procedimientos públicos
procedure SaveConfig;
procedure ReadConfig;
que (luego de presionar Ctrl + Shift +C) implementamos así
procedure TOpciones.SaveConfig;
begin
WriteComponentResFile('C:\Config.dat',Self);
end;
procedure TOpciones.ReadConfig;
begin
if fileexists('C:\Config.dat') then
try
{»»} Self := TOpciones(ReadComponentResFile('C:\Config.dat', Self));
except
end
end;
Si queremos utilizar el registro de windows debemos realizar unos pequeños cambios:
procedure TOpciones.SaveConfig;
begin
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKey('\Software\NiceDemo', True) then
{»»} WriteString('SillySection', ComponentToString(Self));
CloseKey;
finally
Free;
end;
end;
procedure TOpciones.LoadConfig;
begin
with TRegistry.Create do
try
RootKey := RegKey;
if OpenKey('\Software\NiceDemo', False) then
begin
S := ReadString('SillySection');
if S <> '' then
{»»} Self := TOpciones(StringToComponent( S ));
CloseKey;
end;
finally
Free;
end;
end;
Ważne artykuły