MethodAddress
Método definido em TObject, retorna o endereço de um método published. Ou seja, um método definido na seção “published”. Entretanto, evocar o “MethodAddress” não é algo tão trivial. É preciso criar uma variável do tipo “procedure” que receberá o ponteiro para o método retornado por “MethodAddress”.
Exemplo 1:
Exemplo 1:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) BitBtn1: TBitBtn; procedure BitBtn1Click(Sender: TObject); private public published procedure MyZnMethod; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); var AuxProcedure: Procedure(Sender: TObject); begin AuxProcedure := Self.MethodAddress('MyZnMethod'); AuxProcedure(Self); end; procedure TForm1.MyZnMethod; begin Self.Caption := 'Estação ZN'; Self.Color := clAqua; Self.Update; Self.Canvas.TextOut(12, 130, 'Dummy MethodAddress Teste Estação ZN!!!'); end; end.
Ok, muito simples! Só que se eu desejar evocar um método que está definido em outra classe terei de usar uma estratégia, pois o método MethodAddress, só conhece os métodos definidos na própria classe. Para exemplificar, vamos criar uma classe ‘TMyZnClassDummy’ e no mesmo evento OnClick do BitBtn1 evocar o método “Dummy” da nova classe, “TMyZnClassDummy”. Exemplo2:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) BitBtn1: TBitBtn; procedure BitBtn1Click(Sender: TObject); private public ppublished procedure MyZnMethod; end; type TMyZnClassDummy = Class(TComponent) private protected published procedure Dummy; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); var AuxProcedure: Procedure(Sender: TObject); AuxProcedureBlah: Procedure(Sender: TObject); begin AuxProcedure := Self.MethodAddress('MyZnMethod'); AuxProcedure(Self); (*Testando o Blah*) ShowMessage('Testando o Blah!!'); AuxProcedureBlah := MethodAddress('Dummy'); AuxProcedureBlah(Self) end; procedure TForm1.MyZnMethod; begin Self.Caption := 'Estação ZN'; Self.Color := clAqua; Self.Update; Self.Canvas.TextOut(12, 130, 'Dummy MethodAddress Teste Estação ZN!!!'); end; { TMyZnClassDummy } procedure TMyZnClassDummy.Dummy; begin ShowMessage(Self.Name + ' Blah!!!!'); end; end.
Como eu posso fazer para conseguir executar o método “Dummy”? Eu preciso (primeiro, se for o caso fazer uses da unit onde a classe, cujo o método desejo evocar, se encontra) criar na classe que vai chamar através do “MethodAddress” um outro método pblished, este por sua vez chamara o método definido na outra classe. Vou Criar no Form1 um método que evocará o método “Dummy” da classe “TMyZnClassDummy”.Exemplo:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) BitBtn1: TBitBtn; procedure BitBtn1Click(Sender: TObject); private public published procedure MyZnMethod; procedure ExeucteDummy; end; type TMyZnClassDummy = Class(TComponent) private protected published procedure Dummy; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); var AuxProcedure: Procedure(Sender: TObject); AuxProcedureBlah: Procedure(Sender: TObject); begin AuxProcedure := Self.MethodAddress('MyZnMethod'); AuxProcedure(Self); (*Testando o Blah*) ShowMessage('Testando o Blah!!'); (* Executo o Método procedure do Form1 "ExeucteDummy" *) AuxProcedureBlah := MethodAddress('ExeucteDummy'); AuxProcedureBlah(Self) end; procedure TForm1.ExeucteDummy; var MyZnClassDummy: TMyZnClassDummy; begin MyZnClassDummy := TMyZnClassDummy.Create(Self); try MyZnClassDummy.Dummy; finally MyZnClassDummy.Free; end; end; procedure TForm1.MyZnMethod; begin Self.Caption := 'Estação ZN'; Self.Color := clAqua; Self.Update; Self.Canvas.TextOut(12, 130, 'Dummy MethodAddress Teste Estação ZN!!!'); end; { TMyZnClassDummy } procedure TMyZnClassDummy.Dummy; begin ShowMessage(Self.ClassName + ' Blah!!!!'); end; end.
Baseado nisso, podemos criar um catálogo de métodos de classes distintas, os quais poderão ser exibidos numa interface, permitindo ao usuário uma forma de setup da aplicação. De maneira que ele possa definir que funcionalidade será executada a partir de uma determinada ação na interface. Sei que esse tipo de abordagem não é nada convencional, contudo acredito ela permita um flexibilização poderosa para algumas situações.
"A mente que se abre a uma nova idéia jamais voltará ao seu tamanho original". Albert Estein
Nenhum comentário:
Postar um comentário