Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Extender funcionalidad evento

Hola, me presento en el foro con una duda sobre eventos.
Mi intención es que cuando se lance el evento OnDataChange de un TDataSource se ejecute un fragmento de código propio para después mantener el comportamiento original mendiante inherited.
Para ello he creado un componente nuevo que hereda de TDataSource y he intentado rescribir el evento OnDataChange ya que es requisito que todo el código implementado quede dentro del componente.

Lo que he realizado es lo siguiente:
Código Delphi [-]
unit IDSDataSource;

interface

uses
  SysUtils, Classes, DB, Dialogs;

type
  TIDSDataSource = class(TDataSource)
  private
    procedure IDSDataSource1DataChange(Event: TDataChangeEvent);
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    property OnDataChange: TDataChangeEvent write IDSDataSource1DataChange;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('IDS', [TIDSDataSource]);
end;

procedure TIDSDataSource.IDSDataSource1DataChange(Event: TDataChangeEvent);
begin
  ShowMessage('¡Entro aquí!');

  inherited;
end;

end.
¿Voy por el buen camino? No consigo que entre en la rutina MiDataSource1DataChange.

Muchas gracias por vuestro tiempo, un saludo.

Última edición por ecfisa fecha: 14-12-2011 a las 16:55:02. Razón: Corregir problema interfaz WYSIWYG
Responder Con Cita
  #2  
Antiguo 13-12-2011
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Hola kamuspik, bienvenido al foro. ¿Te has pasado por la Guía de Estilo?

Respecto a tu pregunta, no, no vas por buen camino. Es más, por lo que te leo me temo que no sabes cómo implementa Delphi la Programación Dirigida por Eventos. Si nunca antes has hecho PDE en Delphi, Builder ni Lazarus o similar te recomiendo que busques y te leas La Cara Oculta de Delphi, que el propio autor publicó en Internet para su acceso libre. Si no recuerdo mal, en el FTP del Club hay una copia.

Delphi implementa PDE usando propiedades y no vía métodos, como el caso de (por ejemplo) Objective C en NEXT. Para implementar un evento lo que hay que hacer es asignar a dicha propiedad una referencia a un método. En tu caso, después de añadir al formulario un objeto TDataSource, debes ir a la ventana de propiedades del objeto y asignar el método apropiado (con doble pulsación se crea automáticamente) y escribir ahí el código. No necesita herencia.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine

Última edición por Ñuño Martínez fecha: 13-12-2011 a las 15:53:43.
Responder Con Cita
  #3  
Antiguo 13-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Hola, gracias por contestar.
Todavía no domino demasiado Delphi, tengo un ejemplar de la Cara Oculta de Delphi que suelo consultar con frecuencia pero no he encontrado respuesta a este problema. Quizás no me haya explicado bien, entiendo como implementar eventos (por ejemplo, los asociados a un botón) pero mi intención no es esa, lo que pretendo hacer (que no sé si es posible) es extender la funcionalidad de un evento. Quiero que cuando se genere un evento (OnDataChange) se ejecute cierto fragmento de código y que después se haga un inherited para que mantenga su funcionamiento "natural" como evento.
En la ayuda de Delphi lo trata como "Changing the standard event handling", pero no da demasiadas pistas y me he quedado bloqueado.
Un saludo y gracias de nuevo
Responder Con Cita
  #4  
Antiguo 13-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
He encontrado en la guía del desarrollador de componentes de Delphi un caso análogo al que me interesa, pero respecto al evento Onclick:

Código Delphi [-]
procedure Click override { forward declaration }
...

procedure TMyControl.Click;
begin
inherited Click; { perform standard handling, incluiding calling handler }
... { your customizations go here }
end;

Espero que esto ayude a mi pobre explicación.

Un saludo.
Responder Con Cita
  #5  
Antiguo 14-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Hola, revisando un poco de bibliografía he conseguido dar con lo que me interesaba. Lo pongo a continuación por si le sirve a alguien.

Código Delphi [-]
type
  TMiDataSource = class(TDataSource)
  private

    procedure MiDataSourceOnDataChange (Sender: TObject; Field: TField);
  protected

  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
  end;

procedure Register;

implementation


procedure Register;
begin
  RegisterComponents('Componentes', [TMiDataSource]);
end;

constructor TMiDataSource.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);

  Self.OnDataChange := TMiDataSourceOnDataChange;  //instrucción necesaria para redefinir el evento OnDataChange

end;

destructor TMiDataSource.Destroy;
begin

  inherited destroy;
end;


procedure TMiDataSource.MiDataSourceOnDataChange (Sender: TObject; Field: TField);
begin
    ShowMessage('¡Entro aquí!');

    ....... //Codigo que extiende el comportamiento del evento

    inherited;  //instrucción que mantiene el comportamiento original

end;

end.

Un saludo.
Responder Con Cita
  #6  
Antiguo 14-12-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

Y si a ese componente le asignas un método en su evento OnDataChange, ¿este sigue comportándose como deseas? Has la prueba y verás que no.

Para redefinir el comportamiento de un evento, primero debes identificar cual es el método que dispara ese evento, mayormente en la VCL estos métodos se pueden redefinir, pero parece que para la clase TDataSource el método que llama al evento es privado (DataEvent).

Dicho lo anterior, tu componente debe quedar de la siguiente forma para que funcione:

Código Delphi [-]
type
  TMiDataSource = class(TDataSource)
  private
    // Campo para guardar el manejador de evento definido en tiempo de diseño...
    FOldDataChangeEvent: TDataChangeEvent;

    procedure DoOnDataChange (Sender: TObject; Field: TField);
  protected
    procedure Loaded; override;
  end;

implementation

procedure TMiDataSource.DoOnDataChange(Sender: TObject; Field: TField);
begin
  // Llamamos el manejador de eventos asignado en tiempo de diseño...
  if Assigned(FOldDataChangeEvent) then
    FOldDataChangeEvent(Sender, Field);
  // Aquí pones tu código...
end;

procedure TMiDataSource.Loaded;
begin
  inherited;
  // Si estamos en tiempo de ejecución, sustituimos el manejador de evento de OnDataChange con el nuestro...
  if not csDesigning in ComponentState then
  begin
    FOldDataChangeEvent := OnDataChangeEvent;
    OnDataChangeEvent := DoOnDataChange
  end
end;

Toma en cuenta que este código lo hago al vuelo, así que podría fallar. También ten en cuenta que si se cambia el manejador de evento de OnDataChange en tiempo de ejecución, el comportamiento de este código ya no será el deseado.



Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #7  
Antiguo 16-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Hola!
Gracias por tu respuesta, pensé que había resuelto el problema...de hecho el código parecía funcionar como quería. Voy a probar esto que has dicho y luego comento los resultados.

Un saludo
Responder Con Cita
  #8  
Antiguo 16-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Hola maeyanes,
he probado tu código y funciona correctamente. Lo único que no consigo entender la diferencia entre lo que hacía yo y tu código.
A ver si me puedes ayudar a entenderlo, yo directamente asigno el procedimiento que quiero que se ejecute al evento y después hago un inherited.¿Por qué no se comporta como deseo?
En tu código guardas una copia del manejador de eventos y después la llamas antes de ejecutar el procedimiento ¿esto es para mantener el funcionamiento natural del evento no?¿Qué diferencia hay entre los dos comportamientos?

Muchas gracias por tu tiempo,

Un saludo.
Responder Con Cita
  #9  
Antiguo 16-12-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

La única diferencia entre tu código y el mio, es que si se asigna un manejador de evento en tiempo de diseño, tú código ya no va a funcionar como lo tienes pensado, esto es por que al asignar el nuevo manejador de evento este sustituye al que tu asignaste por código en el constructor.

El código que yo te proporcioné prevee este caso y asigna el manejador de evento interno después de "cargar" el component desde el DFM, guardando en un campo la referencia al posible manejador de evento asignado en tiempo de diseño. Luego, al dispararse el evento, el manejador interno llama primero (y puedes hacerlo también al final, depende de lo que desees hacer) al manejador asignado en tiempo de diseño (si es que se asigno uno) y luego ejecuta el código de lo que deseas implementar.

Espero que con esta pequeña explicación te quede más claro.


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #10  
Antiguo 19-12-2011
kamuspik kamuspik is offline
Miembro
NULL
 
Registrado: oct 2011
Posts: 11
Poder: 0
kamuspik Va por buen camino
Muchas gracias, ahora ya lo comprendo, el código que había puesto antes se comportaba de forma excluyente y mi intención era que se mantuviera la posibilidad de asignar un manejador de eventos en tiempo de diseño.

Un saludo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como extender componentes de la paleta mcbullrich OOP 5 01-11-2011 19:27:57
Extender escritorio de windows y bloquear acceso Ivanzinho Windows 2 11-03-2009 12:20:38
DBGrid - funcionalidad / documentación alquimista_gdl PHP 0 09-09-2008 18:15:36
funcionalidad parecida a la del TDBLookUpComboBox.. pvizcay OOP 8 20-09-2006 22:22:15
Funcionalidad del TeamSourse jmedina Varios 3 23-02-2005 18:21:11


La franja horaria es GMT +2. Ahora son las 11:34:06.


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
Copyright 1996-2007 Club Delphi