Ver Mensaje Individual
  #5  
Antiguo 30-10-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.114
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

"ManejadorEvento" es un procedimiento declarado y disponible que cumple con el prototipo del evento que se quiere "manejar". ¿Un ejemplo? El que nos ocupa, verás.

Antes de nada podemos comprobar que el evento "OnClick" es del tipo "TNotifyEvent" (muy común en Delphi) y su declaración es la siguiente:

Código Delphi [-]
TNotifyEvent = procedure(Sender: TObject) of object;

Esto quiere decir que el manejador del evento "OnClick" ha de ser un prodecimiento, mejor dicho un método (pues pertenecerá a un objeto), que cuenta con un solo parámetro de tipo "TObject".

Bastaría con declarar e implementar un método de ese tipo para poder estar al tanto cuando se dispare el evento "OnClick". Como hemos de proveer el procedimiento como un método de un objeto, lo haremos utilizando un "TForm", que puede ser un formulario de tu aplicación.

Aquí ves la declaración ("interface") de un formulario de ejemplo, tal como aparece al iniciarse un proyecto en Delphi y que no cuenta sino con un botón que luego utilizaremos para seguir con lo que nos ocupa.

Código Delphi [-]
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Como ves dentro del formulario hay un botón y un método que responderá al evento "OnClick" de dicho botón. El código fuente anterior se encargó de escribirlo el diseñador de Delphi. Nosotros vamos a añadir por nuestra cuenta un procedimiento que se encarge del evento "OnClick" de otro botón, esta vez creado en tiempo de ejecución.

Código Delphi [-]
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ManejadorEventoOnClick(Sender: TObject);
  public
    { Public declarations }
  end;

Como puedes ver los métodos "Button1Click" y "ManejadorEventoOnClick" tienen el mismo prototipo: mismo número de parámetros, y así podrían utilizarse indistintamente, es decir, al botón que luego crearemos en tiempo de ejecución podríamos darle cualquiera de los dos métodos para que manejase su evento "OnClick", puesto que son iguales, como queda dicho.

Ahora vamos a la implementación del método. Se trata de que lo declarado en la cláusula "interfaz" de las unidades de Delphi ha de estar implementado, precisamente, en la cláusula "implementation". Lo vemos mejor en el propio código fuente, concretamente, con el de toda la unidad de nuestro formulario:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ManejadorEventoOnClick(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Ya lo usaremos luego
end;

procedure TForm1.ManejadorEventoOnClick(Sender: TObject);
begin
  ShowMessage('¡Hola desde el manejador del evento OnClick!');
end;

end.

Ahí puedes ver que ya prepramos la implementación del método "ManejadorEventoOnClick", es decir, ya podríamos utilizarlo perfectamente. Entonces vamos a crear un botón en tiempo de ejecución y vamos a asignarle el manejador oportuno para su evento "OnClick".

Para abreviar lo haremos en el otro evento "OnClick", es decir, en el que fue creado en tiempo de diseño para el botón que también añadimos a nuestro formulario en tiempo de diseño, con ayuda de Delphi. También por abreviar, declararemos una variable "global" que se dedique a guardar la instancia de nuestro botón creado en tiempo de ejecución:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ManejadorEventoOnClick(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Boton: TButton; // Nuestro botón

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Creamos el botón
  Boton := TButton.Create(Self);

  // Le damos un padre como tiene que ser
  Boton.Parent := Self; // Este mismo formulario

  // Lo situamos en el formulario
  Boton.SetBounds(20, 20, 100, 25);

  // Y un Caption para verlo mejor
  Boton.Caption := '¡Haz clic aquí!';

  // Y al fin un manejador para su evento "OnClick"
  Boton.OnClick := ManejadorEventoOnClick;
end;

procedure TForm1.ManejadorEventoOnClick(Sender: TObject);
begin
  ShowMessage('¡Hola desde el manejador del evento OnClick!');
end;

end.

Hecho lo anterior, cuando se haga "clic" en el botón creado en tiempo de diseño ("Button1") se disparará el evento correspondiente (asignado también en tiempo de diseño ("Button1Click") y en este instanciaremos el botón que creamos en tiempo de ejecución.

Luego de lo dicho ya podríamos ver en nuestro formulario el botón que creamos en tiempo de ejecución, además del que creamos en tiempo de diseño, y, cuando se haga "clic" en el primero se disparará su evento "OnClick", es decir, se ejecutará el código del método "ManejadorEventoOnClick" y podremos ver el mensaje "¡Hola desde el manejador del evento OnClick!".

Y eso es todo. Como al botón le dimos como padre el formulario en que se encuentra, cuando se destruya el formulario se destruirá también el botón, es decir, la instancia del botón que creamos en tiempo de ejecución será liberada de igual forma que se hará con la instancia del botón que creamos en tiempo de diseño.

Sin embargo, creo que es una buena práctica asegurarse de que las instancias de que nosotros nos hacemos cargo (en tiempo de ejecución) sean liberadas también por nuestra cuenta, para lo que podríamos utilizar el propio evento "OnDestroy" de nuestro formulario. Algo así, vaya:

Código Delphi [-]
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Boton.Free; // Fue un placer Boton
end;

A continuación y cayendo en la prolijidad el código fuente de toda la unidad de nuestro formulario:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    procedure ManejadorEventoOnClick(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Boton: TButton; // Nuestro botón

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Creamos el botón
  Boton := TButton.Create(Self);

  // Le damos un padre como tiene que ser
  Boton.Parent := Self; // Este mismo formulario

  // Lo situamos en el formulario
  Boton.SetBounds(20, 20, 100, 25);

  // Y un Caption para verlo mejor
  Boton.Caption := '¡Haz clic aquí!';

  // Y al fin un manejador para su evento "OnClick"
  Boton.OnClick := ManejadorEventoOnClick;
end;

procedure TForm1.ManejadorEventoOnClick(Sender: TObject);
begin
  ShowMessage('¡Hola desde el manejador del evento OnClick!');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Boton.Free; // Fue un placer Boton
end;

end.

En cuanto al error que mencionas... ah, espera, que no mencionas ningún error. Decir que te da un error no es decir mucho: expón por aquí el error que te encuentras, su mensaje, pues que puede aportar información útil para tratar de ayudarte.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita