PDA

Ver la Versión Completa : Evitar perder valores asignados en el constructor de un objeto


dec
30-06-2006, 13:37:55
Creo un componente y asigno valores a propiedades en el constructor, pero cuando la aplicación se ejecuta, estos valores se pierden ¿cómo es posible?

Pues en este caso hay que tener presente que éstas se almacenan en el recurso RCDATA correspondiente a la ficha.

Delphi crea primero el ejemplar del componente y después lee sus propiedades publicadas desde el fichero DFM, que el enlazador insertó dentro del ejecutable, como recurso de Windows.

Por tanto lo asignado en el constructor queda como "valor por defecto", siendo machacado por lo leído del DFM.

Te en cuenta que si publicas una propiedad es para que el usuario del componente pueda modificar su valor. Si no quieres que pueda cambiarla en diseño, no la incluyas en la sección "published" sino en la "public".

De todas formas tienes una última oportunidad de modificar los valores de las propiedades después de que el componente haya sido cargado. El método "Loaded" se ejecuta inmediatamente después de que se haya producido la carga de las propiedades.

El siguiente componente de prueba te ayudará a entender la secuencia.

Si lo pones en una ficha te saldrán los mensajes esperados en diseño. Pero si pones algo en la propiedad "Caption" en diseño, digamos la cadena "Establecida en diseño", y seguidamente ejecutas, te darás cuenta de que el constructor es previo a la lectura


unit TestPanel;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ExtCtrls;

type
TTestPanel = class(TPanel)
public
constructor Create( AOwner: TComponent ); override;
procedure Loaded; override;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TTestPanel]);
end;

constructor TTestPanel.Create( AOwner: TComponent );
begin
inherited Create( AOwner );
ShowMessage( 'Caption al entrar en el constructor: ' + Caption );
Caption := 'Establecida en el constructor';
ShowMessage( 'Caption al salir del constructor: ' + Caption );
end;

procedure TTestPanel.Loaded;
begin
ShowMessage( 'Caption al entrar en "Loaded": ' + Caption );
Caption := 'Cambiada en "Loaded"';
inherited Loaded
end;

end.