PDA

Ver la Versión Completa : Método accesible desde varios controles en diferentes forms


athlontado
27-10-2004, 18:12:26
Muy buenas.

Quisiera saber si hay alguna forma de crear un método que se pueda asignar a un evento (OnKeyPress, por ejemplo) de varios controles (TEdit, p.ej.) desperdigados por varios Formularios ó Units, ya sea creándolo en una clase para éste propósito ó como un método aislado (no sé si habré dicho alguna burrada que rompa con las reglas de la POO :eek:).

Un saludo.

defcon1_es
27-10-2004, 18:38:34
Hola, para esto hay 2 soluciones (o más, pero no se me ocurren ;))

1) Crear un descendiente de la clase del componente que quieres y sobreescribir el método en cuestión.

type
tMiClaseHija = class(TClase_Padre);
...
protected
...
procedure DoClick; override;
...
end;

Esto implica que, si quieres asignar el mismo código al evento OnClick de objetos de distintas clases (TBitBtn y TButton), debes implementarlo en los descendientes que te crees de esas clases...
Y si tienes que modificar el código de ese evento, debes hacerlo en todas las clases descendientes que hayas creado.

2) Crear un evento "genérico" con argumentos compatibles con el evento que deseas asignar, p.ej.:
procedure Mi_Manejador_de_EventoClick(Sender: TObject);
begin
....
// Código que se ejecutará cuando invoque el evento.
....
end;

procedure TForm1.FormShow(Sender: TObject);
begin
....
MiBoton.OnClick := Mi_Manejador_de_Evento;
....
end;

Esta 2ª opción sirve para objetos de distintas clases, p. ej., para un TBitBtn y un TButton (ambos tienen el evento OnClick con el mismo argumento).
Y si tienes que modificar el código de ese evento, lo haces en un sólo sitio.

Depende de tus necesidades ;)

Salu2.

roman
27-10-2004, 19:03:23
procedure TForm1.FormShow(Sender: TObject);
begin
....
MiBoton.OnClick := Mi_Manejador_de_Evento;
....
end;

Aquí va a protestar el compilador. No puedes asignar un procedimiento regular a una propiedad de un objeto, sólo puedes asignarle métodos.

Lo que puede hacer en todo caso es:


type
TEventos = class
class procedure EventoClick(Sender: TObject);
end;

...

MiBoton.OnClick := TEventos.EventoClick;


El uso de class procedure es para no tener que crear un objeto de la clase TEventos.

// Saludos

athlontado
27-10-2004, 19:07:40
Gracias roman, eso es justo lo que necesitaba. Gracias también a defcon1_es por intentarlo, yo estaba parado justo donde roman nos corrigió.

Saludos.

defcon1_es
28-10-2004, 11:03:11
Hola Roman,
se me olvidó mencionar que el procedure "genérico" es del TForm1.

Acabo de probar esto y el compilador no se queja... y funciona.


type
TForm1 = class(TForm)
Button1: TButton;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
procedure Mi_Manejador_de_EventoClick(Sender: TObject);
end;
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
Button1.OnClick := Mi_Manejador_de_EventoClick;
end;

procedure TForm1.Mi_Manejador_de_EventoClick(Sender: TObject);
begin
ShowMessage('Hola');
end;

Lepe
28-10-2004, 11:34:29
Si es de TForm1, entonces para referenciarlo sería algo así:

Form2.button1.OnClick := Form1.Mi_Manejador_de_Evento;

Lo que implica que form1 deberá estar instanciado para poder acceder a ese método. Si form1 es la forma Principal de la aplicación, sin problemas; pero si no lo es, empiezan los problemas.

Saludos

ruina
28-10-2004, 15:11:29
una vuelta mas de tuerca:

dado que lo único que necesitamos para asignar el evento es que le pasemos un "procedure of object" esto es, un método de un objeto en lugar de una función clásica, podemos hacer una clase dummy (que no haga nada) y para ahorrarnos la creación destrucción etc, hacer que el método sea un método de clase:


Tdummy = class
class procedure MiEventoClick(sender:tobject);
end;


no pongo private ni public ni na porque los métodos de clase siempre son publicos.

roman
28-10-2004, 15:28:17
Acabo de probar esto y el compilador no se queja... y funciona

Claro, una vez corregido ;)



Tdummy = class
class procedure MiEventoClick(Sender: tObject);
end;


¿Qué no es lo mismo que puse arriba?



TEventos = class
class procedure EventoClick(Sender: tObject);
end;



no pongo private ni public ni na porque los métodos de clase siempre son publicos

Esto no es cierto. Los métodos de clase, como cualquier otro método pueden ser privados, públicos o protegidos.

// Saludos

ruina
29-10-2004, 14:59:02
!_! dios santo, estoy ciego!
xD

que desastre soy, supongo que tanto leer entre lineas me ha producido el efecto inverso, osea, leer menos de lo que dice.
Mil perdones.


y respecto a lo de los métodos de clase ... me has hecho dudar y todo, quizas en otros lenguajes tipo java deje hacerlo pero en delphi la visibilidad de los métodos de clase es public siempre.
ej.:

tdummy = class
private
class procedure feo(sender:tobject);
end;


no solo no se queja el compilador, sino que se ejecuta sin problemas.

roman
29-10-2004, 16:10:16
y respecto a lo de los métodos de clase ... me has hecho dudar y todo, quizas en otros lenguajes tipo java deje hacerlo pero en delphi la visibilidad de los métodos de clase es public siempre.


tdummy = class
private
class procedure feo(sender:tobject);
end;


no solo no se queja el compilador, sino que se ejecuta sin problemas.
El compilador no tiene por qué quejarse de una declaración como ésta, pero el hecho es que no todos los métodos de clase son públicos. Si declaras un método de clase en la sección private sólo podrás acceder a él desde la misma unidad y si lo declaras en la sección protected sólo podrás acceder a él desde descendientes. Ante la duda que yo mismo tuve ayer lo probé y es como te digo.

// Saludos