Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ¿Se puede "robar" un evento? (https://www.clubdelphi.com/foros/showthread.php?t=69875)

ElDuc 15-09-2010 10:11:46

¿Se puede "robar" un evento?
 
Hola a todos,

Estoy haciendo una clase en una unidad independiente, desde la cual me interesaría "utilizar" (no "robar", ahora comprenderéis lo de robar) el evento OnResize del formulario que la utiliza.

No estoy haciendo un componente derivado de la clase TForm, lo que deseo es que cuando el formulario cambia de tamaño, mi nueva clase se entere, ejecute un código y devuelva el control al evento OnResize del formulario por si hay codigo en él.

Todo esto debería ser opaco para el formulario.

Por el momento he conseguido "robar" el evento del Formulario:

Código Delphi [-]
...
 
Interface
 
Type
  MyClass=Class
  Private
    FTheForm:TForm;
    Procedure MyOnResize(Sender:TObject);
  Public
    Constructor Create(AOwner:TForm);
  End;
 
Implementation
 
Procedure MyClass.MyOnResize(Sender:TObject);
Begin
Beep;
End;
 
Constructor MyClass.Create(AOwner:TForm);;
Begin
FTheForm:=AOwner;
FTheForm.OnResize:=MyOnResize
End;
 
End.

Con este código si si se cambia el tamaño del formulario se ejecuta el código de MyOnResize y genera un pitido, pero lo que hago es "ROBAR" el evento ya que si en el evento OnResize del formulario hemos puesto código. éste no se ejecuta.

Me imagino que esto sucede porque al apuntar el evento OnResize del formulario a mi propio evento MyOnResize ya no se ejecuta el antiguo evento.

Me imagino que debe haber una forma de almacenar el evento antiguo antes de reasignarlo para que una vez ejecutado el código del nuevo evento pudiera llamar al código del evento OnResize del formulario pero no sé como hacerlo.

¿Podéis ayudarme?

Neftali [Germán.Estévez] 15-09-2010 10:55:58

Cita:

Empezado por ElDuc (Mensaje 376506)
Me imagino que debe haber una forma de almacenar el evento antiguo antes de reasignarlo para que una vez ejecutado el código del nuevo evento pudiera llamar al código del evento OnResize del formulario pero no sé como hacerlo.
¿Podéis ayudarme?

Pues tú mismo te has dado la solución.

Código Delphi [-]
  FTheForm := Value;
  // Me guardo el antiguo
  oldResize := FTheForm.OnResize;
  // Apunto al mío
  FTheForm.OnResize := MyOnResize

ElDuc 15-09-2010 11:03:12

Solucionado
 
Ya lo he solucionado, lo explico por si a alguien le puede interesar.

Código Delphi [-]
...

Interface

Type
  MyClass=Class
  Private
    FOld:NotifyEvent;   // Aquí almacenaremos el viejo evento
    FTheForm:TForm;
    Procedure MyOnResize(Sender:TObject);
  Public
    Constructor Create(AOwner:TForm);
  End;

Implementation

Procedure MyClass.MyOnResize(Sender:TObject);
Begin
Beep;   // Ejecutamos nuestro código
 
FTheForm.OnResize:=FOld;   // Apuntamos al evento del TForm
FTheForm.OnResize(Sender);   // Lo llamamos
FTheForm.OnResize:=MyOnResize   // Volvemos a apuntar a nuestro código
End;
 
Constructor MyClass.Create(AOwner:TForm);;
Begin
FTheForm:=AOwner;
FOld:FTheForm.OnResize;   // Almacenamos el evento del TForm
FTheForm.OnResize:=MyOnResize
End;
 
End.

Co este código se consigue lo que yo deseaba, es decir, ejecutar nuestro código y posteriormente el que hay en el evento OnResize del Formulario.

Saludos.

Neftali [Germán.Estévez] 15-09-2010 16:40:04

Es más o menos eso, aunque creo que no es necesario que cada vez hagas la asignación de los eventos.
Al principio (al crear el componente o al asignar el form) te quedas con el apuntador al form y luego sólo debes lanzar el evento cuando toque.

maeyanes 20-09-2010 16:24:11

La forma correcta, tal como dice Neftali sería:

Código Delphi [-]
constructor MyClass.Create(AOwner: TComponent);
begin
  inherited;
  FTheForm := AOwner;
  FOldResize := FTheForm.OnResize;
  FTheForm.OnResize := MyOnResize
end;

procedure MyClass.MyOnResize(Sender: TObject);
begin
  // Mi código...
  if Assigned(FOldResize) then
    FOldResize(Sender)
end;

Ahora, si tu clase es un componente, la asignación del evento deberías hacerla redefiniendo el método Loaded:

Código Delphi [-]
  MyClass = class(TComponent)
  protected
    procedure Loaded; override;
  end;

implementation

procedure MyClass.Loaded;
begin
  inherited;
  // Verificamos que estemos en tiempo de ejecución y solo así cambiamos la asigación
  // del evento OnResize
  if not (csDesigning in ComponentState) then
  begin
    FOldResize := FTheForm.OnResize;
    FTheForm.OnResize := MyOnResize
  end
end;


Saludos...


La franja horaria es GMT +2. Ahora son las 05:59:25.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi