Ver Mensaje Individual
  #1  
Antiguo 30-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Evitar perder valores asignados en el constructor de un objeto

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

Código Delphi [-]
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.
Responder Con Cita