PDA

Ver la Versión Completa : Saber qué procedimento tiene asignado un evento


Ohcan
21-06-2005, 11:57:00
Hola a todo el mundo

Una cosilla... que me tiene mosqueado.

Quiero saber si un evento de un componente está asignado (ésto lo hago con Assigned(MiObj.OnExit) y funciona), pero además quiero saber a qué procedimiento está asignado.

Inentaré explicarme :D

El OnExit (p. ej.) puede estar asignado (con el inspector de objetos) a TForm1.MiObjExit, pero también a TForm1.OtroProcedimento (ya sea en el inspector de objetos o por código (MiObj.OnExit := OtroProcedimiento).
He visto en la ayuda de Delphi (Procedural types in statements and expressions) que sería:
if @MiObj.OnExit=@OtroProcediemiento then ...;
pero no me compila (Me canta: Variable required);

Y mi pregunta es :
¿puedo saber de alguna manera a cuál de ambos lo está ?

Espero que "me se entienda" ;) Yo sigo investigando...

Y muchas gracias :):)

Neftali [Germán.Estévez]
21-06-2005, 13:42:10
Lo más aproximado que veo que puedes hacer es algo como ésto:


var
Routine : TMethod;
p1:Pointer;
Str:String;
begin
// Acceso a la rutina
Routine.Data := Pointer(Edit1);
// Devuelve la dirección de un método published
Routine.Code := Self.MethodAddress('MyExit');
// a encontrado el código de la rutina...
if (Routine.Code <> nil) then begin

p1 := @Edit1.OnExit;

if (p1 = Routine.Code) then begin
MessageDlg('Edit tiene asignado el MyExit', mtInformation, [mbOK], 0);
end
else begin
MessageDlg('Edit no tiene asignado el MyExit', mtInformation, [mbOK], 0);
end;
end
else begin
MessageDlg('No encuentra el procedimiento MyExit', mtError, [mbOK], 0);
end;


Lo que puedes hacer es comprobar si es un método determinado. Es decir primero programas tu método en el form (como published) y luego puedes comprobar si está apuntando a ese. En todo caso puedes saber a qué método apunta si es que está definido como published en el form, utilizando: MethodName
Algo así:


Str := Self.MethodName(@Edit1.OnExit);


Pero sólo te devolverá el nombre si está apuntando a un método definido como published en el form (ya que se hace vía RTTI). En ese caso sí obtendrás el nombre.

La clase está definida de ésta forma:


type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Edit1Enter(Sender: TObject);
procedure Edit1Exit(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
published
{ Public declarations }
procedure MyExit(Sender: TObject);
end;

Ohcan
21-06-2005, 13:56:38
Muchas Gracias

He optado por la segunda opción:

[...] //El procedure TForm1.ExitPag está declarado como published
var
I:Integer;
Pag:TTabSheet;
begin
for I := 0 to PageControl.PageCount-1 do
begin
Pag := PageControl.Pages[I];
if Assigned(Pag.OnExit) then
begin
if MethodName(@Pag.OnExit)='ExitPag' then ShowMessage(Pag.Name + ': ExitPag')
else ShowMessage(Pag.Name + ': el propio, ' + MethodName(@Pag.OnExit));
end
else ShowMessage(Pag.Name + ': exit no asignado');
end;
end;


Y va perfectamente.

Saludos.