Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
Suma de eventos

Buenas, en mi caso es con eventos de qreports, pero yo supongo que puede usarse en los eventos de cualquier componente, por esto lo he puesto en este foro.

La pregunta es:

Yo me repaso una serie de componentes del formulario, y segun unas caracteristicas, les pongo en su evento, otro evento,que es el mi propio evento.

Pues bien,el problema reside, cuando el evento tenia ya codigo asignado.

¿como puedo yo en ese caso hacer que primero, ejecute el código que tenia ya asignado el evento, y luego el evento que yo le he puesto?

En micaso es con el before print del quick report.

Saludos
Muchas Gracias
Responder Con Cita
  #2  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
La forma típica es guardar ese evento en una variable, y llamarla antes o despues del evento:


Código:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FOldOnClick: TNotifyEvent;
    procedure MiEvento(Sender: TObject);
  public
  end;

implementation

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  FOldOnClick := Button1.OnClick;
  Button1.OnClick := MiEvento;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Hola Mundo!');
end;

procedure TForm1.MiEvento(Sender: TObject);
begin
  if Assigned(FOldOnClick) Then
    FOldOnClick(Self);

  ShowMessage('¿Ok?');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Button1.OnClick := FOldOnClick;
end;
Obviamente este caso es algo inútil, esto se lo suele usar en algún componente que usa los eventos de otro objeto... Por eso lo del Destroy y el Assigned


Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
Muchas gracias, ahora luego probare, aunque por el codigo que veo, esta bastante claro, i creo que no tendre ningun problema

Gracias de nuevo

saludos
Responder Con Cita
  #4  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
perdona una cosa, me da el error de incompatible types de tobject and tqrcustomband.

Claro el tnotify event es para un tobject, y ¿ tqrcustomband no deriva de tobject?

el error es en esta linea

ant := Tqrcustomband(Components[i]).BeforePrint;

ant es tnotifyevent;

La finalidad, es que de esta manera recorriendome todos los componentes del form, cuando yo veo que son tqrcustomband, guardarme su beforeprint en un tnotifyevent.

supongo que tendre que hacer una array de tnotifyevent.¿Se puede no?

¿hacer un cast de Tqrcustomband a tobject, sera la solucion?

Gracias por la ayuda
Responder Con Cita
  #5  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
ok yo mismo me respondo que lo encontre

TQRBandBeforePrintEvent

Saludos

Y muchas gracias por todo
Responder Con Cita
  #6  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Descendents comentó:
Claro el tnotify event es para un tobject, y ¿ tqrcustomband no deriva de tobject?
TNotifyEvent es un tipo de dato (procedure of object) que como cualquier tipo, es para cualquier tipo de objeto. Lo que tenes que averiguar, es que tipo de evento es BeforePrint (TQRBandBeforePrintEvent)


Cita:
Descendents comentó:
supongo que tendre que hacer una array de tnotifyevent.¿Se puede no?
Puedes hacer un array de cualquier tipo sin problemas.

Cita:
Descendents comentó:
¿hacer un cast de Tqrcustomband a tobject, sera la solucion?
No, por lo expuesto anteriormente.

Código:
var
  FOldEvento: TQRBandBeforePrintEvent;
begin
  FOldEvento := Tqrcustomband(Components[i]).BeforePrint;
  ...
end;
Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #7  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Descendents comentó:
ok yo mismo me respondo que lo encontre...
... Te me has adelantado!!

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 07-01-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Buen día a todos!

Descendents:

¿Por qué no colocas el código específico directamente en el manejador de evento?

¿Será que son manejadores de eventos compartidos y ese código específico no es para todos los objetos, o bien, ese código específico se requiere también en otras rutinas?

Mencionas algo de "según unas características". ¿Podrías ser un poco más específico?

Me gustaría entender con mayor precisión el problema, para ayudar en la medida de lo posible.

Muchas gracias.

Al González .
Responder Con Cita
  #9  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
el error esta aqui
if Assigned(ant) Then ant(sender,true);

¿Alguien sabe cual es este error?
[Error] Unit1.pas(72): Types of actual and formal var parameters must be identical

he buscado en la ayuda, pero me habla de que byte no es lo mismo que 0..255.

Pero yo necesito llamar al TQRBandBeforePrintEvent
al tnotifyevent con el self ya estaba, pero aqui me pide un tqrcustomband y un booleano de printband.

es decir esto
procedure TForm1.PageHeaderBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);

¿Porque puede darme este error?

Soy un pesado lo se, pero esto no se como afrontarlo

Gracias
Responder Con Cita
  #10  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
La respuesta está en tu pregunta, fíjate este pequeño detalle:
Código:
procedure TForm1.PageHeaderBand1BeforePrint(Sender: TQRCustomBand; var  PrintBand: Boolean);
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #11  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
Gracias delphi.com.ar, pero mi desconocimiento me precede, y he visto ya bastantes veces procedimientos, con var y parametros, pero como nunca lo he necesitado, no se como se atacan ni para que sirven.

Si fueras tan amable, mataria varios pajaros de un tiro.
Para que sirve,y por que el error, y en que otras ocasiones puede servirme de ayuda

he buscado sobre el tema, pero no se como buscar sobre esto exactamente.

Yo todos los procedimientos y funciones, siempre les pongo unos parametros, y se los paso, nunca he necesitado parsar una variable como paramentro, principalmente porque no tengo ni idea para que sirve

Gracias y perdona la incultura
Responder Con Cita
  #12  
Antiguo 07-01-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 22
marto Va por buen camino
Hola, pongo esta respuesta aquí, porque creo que viene al caso, aunque en realidad no le solucionará la vida a nadie ya que más bien es anecdótica
ültimamente estoy aprendiendo algo de C# y lo cierto es que tiene algunas características muy interesantes y, entre ellas está su implementación de eventos que es lo qua aquí se comenta. El caso es que en C# no puedes asignar un valor a un evento, sino que debes añadir o quitar valores, de manera que, al lanzarse dicho evento se ejecutaran todos los provedimientos "añadidos". Esto és muy, pero que muy potente, ya que en el ejemplo que comentamos, sería algo tan simple como lo siguiente

Código:
  /*en el create del form1, por ejemplo*/
  form2.button1.onClick += metodo1;
  form2.button1.onClick += metodo2;
  form2.button2.onClick += metodo1;
  /*y en el destroy*/
  form2.button1.onClick --;
  form2.button1.onClick --;
  form2.button2.onClick --;
De esta manera, tanto button1 como button2 ejecutarían los eventos que tubiesen asignados antes más metodo1 y, además, button1 ejecutaría metodo2. Al destruir el form, dejamos los eventos tal y como estaban antes.

No me digáis que no es chulo!!!!!!

Sólo he puesto esto como curiosidad espero no haberme excedido.
__________________
E pur si muove
Responder Con Cita
  #13  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Te recomiendo buscar en la ayuda una página titulada "Value and variable parameters"... en simples palabras, existen dos formas de pasar valores en parámetros de procedimientos, por valor y por referencia. Por valor, el parámetro no deja de ser una variable propia del procedimiento que contendrá el valor que le has asignado al parámetro. Por referencia (var), el parámetro apunta a la misma variable que se ha utilizado en el parámetro, al llamar el procedimiento, por lo tanto requiere que sea una variable y no una constante. Al modificar el valor de la función dentro del procedimiento, se modificará el valor de la variable usada al llamar al procedimiento.

La solución a tu problema, es algo como:
Código:
var
  bPrintBand: Boolean;
begin
  bPrintBand := True;
  if Assigned(Ant) Then 
    Ant(Sender, PrintBand);
Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #14  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
ok ya entendi, o eso creo almenos.

Pide una referencia a una variable, no un valor.

Ok gracias.

Aunque si fueran tan amables de decirme si voy bien encaminado
y su utilidad.

Gracias
Responder Con Cita
  #15  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
Mira justo me has respuesto, pues estaba bien encaminado, gracias, buscare más información de todos modos

Muchas gracias,Tema resuelto.

Saludos
Responder Con Cita
  #16  
Antiguo 07-01-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Buen día a todos!

Interesante aportación Marto. Por supuesto que se ve muy práctico. Me pregunto cómo será la implementación interna de Propiedad evento += Manejador de evento, es decir el encadenamiento de manejadores, y si este encadenamiento puede ser establecido tanto de la forma manejador anterior + manejador nuevo, como de la forma manejador nuevo + manejador anterior, es decir, con la libertad establecer su ejecución en cualquier orden. Imagino que quizás C# guarda una lista de todos los manejadores asignados al mismo evento de un objeto, o bien, la estructura de rutinas .NET presenta de forma nativa esta característica.

Sería interesante averiguar si Delphi 8 también permite este tipo de encadenamientos de manejadores de eventos mediante asignaciones.

Lo más parecido que he visto a encadenaciones automáticas de manejadores de eventos, es cuando se define un manejador de evento en una plantilla y en la clase descendiente se vuelve a definir. El segundo llamando al primero con la palabra reservada Inherited (aun sin tratarse de un método virtual). Sin embargo esta aproximación dista mucho de la útil metodología de C# expuesta por Marto.

Por otra parte, le pido a Descendents que por favor atienda mi mensaje anterior, para entender mejor los pormenores del caso y tratar de aportar una solución práctica.

Seguimos en contacto.

Al González.
Responder Con Cita
  #17  
Antiguo 07-01-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Digamos que en Delphi esto no sería imposible, si quisiéramos escribir un poco de código, podríamos crear algo como una Colección de Eventos, y a la hora de definir un evento, lo podemos definir de este tipo. Internamente lo que tendría que hacer nuestro objeto, es recorrer esta colección y llamar a todos los eventos de esta.
Digamos... por el uso que le daríamos a esta, creo que como siempre la ecuación costo/beneficio sería difícil de evaluar.


Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #18  
Antiguo 07-01-2004
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Cita:
No me digáis que no es chulo!!!!!!
Pues si te lo digo es chulísimo.

Un saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #19  
Antiguo 07-01-2004
Descendents Descendents is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona
Posts: 396
Poder: 22
Descendents Va por buen camino
Al gonzalez, perdona, no habia visto tu mensaje anterior, lo he visto a partir de que me dices que te conteste, lo mire y lo vi, perdón.

El tema ya lo tengo solventado, como me guio delphi.com.ar era la manera correcta por donde ir.

quiero asignarle un before print mio, a cada banda del report,pero si ya tenia unos calculos en el before print, estos se pierden, pero ahora esto ya no pasa.

No puedo poner en cada evento el codigo, porque no me sirve de nada, por que entonces tengo que en todos los reports tener que en cada banda ponerle mi código, y yo quiero que esto se haga automatico.

ahora llamo al procedimiento, le paso como paramentro el report, y el solo, me asigna lo que quiero hacer a todas las bandas, indistintamente de las bandas que haya.

La caracteristica principal es, que quiero hacer lo mismo en todas las bandas, indiferentemente de si es un detailband o un pageheader o lo que sea, por eso quiero hacerlo de esta manera

Saludos
Responder Con Cita
  #20  
Antiguo 07-01-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Hola de nuevo!

Gracias por la aclaración Descendents.

Comprendiendo la naturaleza de este caso, debo decir que lo mejor sería crear una nueva clase de objeto banda para Quick Report. Donde el evento BeforePrint esté redefinido. Ejemplo:
Código:
Interface
  ...

  Type
    TBandQuickReport = Class (TQRBand)
      Private
        FBeforePrint :TQRBandBeforePrintEvent;

        { Manejador de Evento Before Print interno }
        Procedure ManeEvenBeforePrint (
          Remitente :TQRCustomBand; Var Imprimir :Boolean);
      Public
        Constructor Create (AOwner :TComponent); Override;
      Published
        { Evento Before Print redefinido (manejador de
          evento externo)                              }
        Property BeforePrint :TQRBandBeforePrintEvent
          Read FBeforePrint Write FBeforePrint;
    End;

  ...
Implementation
  ...

  { TBandQuickReport }

  Constructor TBandQuickReport.Create (AOwner :TComponent);
  Begin
    Inherited Create (AOwner);
    Inherited BeforePrint := ManeEvenBeforePrint;
  End;

  Procedure TBandQuickReport.ManeEvenBeforePrint (
    Remitente :TQRCustomBand; Var Imprimir :Boolean);
  Begin
    { Aquí puede ir código común para todas las bandas }

    { Llamar al manejador de evento BeforePrint externo }
    If Assigned (BeforePrint) Then
      BeforePrint (Self, Imprimir);

    { Aquí puede ir código común para todas las bandas }
  End;
De esta manera, cada banda de clase TBandQuickReport agregada al reporte tendrá internamente el comportamiento deseado, antes o después de dispararse el manejador de evento BeforePrint establecido por el programador final.

Bajo las circustancias que planteas, creo que definitivamente esta es la solución más adecuada. Esto se acostumbra en programación orientada a objetos cuando se tiene una clase y se crea una segunda clase derivada de la primera para agregarle características extras.

Espero esto sea de utilidad. Mantenernos informados.

Al González .
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


La franja horaria es GMT +2. Ahora son las 01:57:30.


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