Em várias classes do Delphi existem certos métodos que recebem como parâmetro de entrada uma ação e essa ação será aplicada a elementos internos da classe.

Pode parecer estranho, já que existe um método ele deveria saber o que fazer. Porém o uso de funções de callback pode dar maior flexibilidade quanto à execução do método.

Essa ação que deverá ser passada ao método, é passada em forma de procedimento ou função que deve ser compatível com tipo indicado.

Um exemplo prático da função de callback

Para compreender melhor o que é uma função de callback vamos a um exemplo que organiza uma lista de objetos, para isso vamos usar a classes TList.

A classe TList possui um método que organiza os itens da coleção de objetos armazenados, esse é o método Sort.

Acima mencionamos que alguns métodos podem receber como parâmetro uma ação, no caso do Sort ele requer uma ação de comparação, ou seja, uma função que faça a comparação de seus elementos internos e deve obedecer a seguinte assinatura:


function (Item1: Pointer; Item2: Pointer): integer;

Crie uma classe TClientes como na Listagem 1.


TClientes = class

  private

    FNome: string;

    FEndereco: string;

    procedure SetNome(const Value: string);

    procedure SetEndereco(const Value: string);

  public

    property Nome: string read FNome write SetNome;

    property Endereco: string read FEndereco write SetEndereco;

end;
Listagem 1. Classe TClientes

Depois, vamos criar as seguintes propriedade e métodos na seção private do formulário principal, Listagem 2.


private

  { Private declarations }

  property ListaClientes: TList read FListaClientes write SetListaClientes;

  procedure EncheListaClientes;

  procedure AtualizaListBox;
Listagem 2. Seção privada do formulário principal

Na Listagem 3 vemos a implementação deles.


procedure TForm1.EncheListaClientes;

begin

  lCliente1 := TClientes.Create;

  lCliente1.Nome := "Paulo";

  lCliente1.Endereco := "Av. Joao Pereira Barreto";

  ListaClientes.Add(lCliente1);

 

  lCliente2 := TClientes.Create;

  lCliente2.Nome := "Andre";

  lCliente2.Endereco := "Av. Ayrton Senna";

  ListaClientes.Add(lCliente2);

 

  lCliente3 := TClientes.Create;

  lCliente3.Nome := "Jair";

  lCliente3.Endereco := "Rua Dom Pedro I";

  ListaClientes.Add(lCliente3);

end;


procedure TForm1.AtualizaListBox;

var

 lIndex: integer;

begin

  ListBox1.Items.Clear;

  for lIndex := 0 to ListaClientes.Count -1 do

      ListBox1.Items.Add(TClientes(ListaClientes[lIndex]).Nome + "-" +   
      TClientes(ListaClientes[lIndex]).Endereco);

end;
Listagem 3. Implementação

Esta na hora de criar as funções de callback, elas é que vão ditar as regras de comparação/ordenação para o método sort do ListaClientes, veja Listagem 4.


var

  Form1: TForm1;

 

function ClassificaPorNome(item1: Pointer; item2: Pointer): integer;

function ClassificarPorEndereco(item1: Pointer; item2: Pointer): integer;

 

function ClassificaPorNome(item1, item2: Pointer): integer;

begin

  result := CompareText(TClientes(item1).Nome, TClientes(item2).Nome);

end;

 

function ClassificarPorEndereco(item1, item2: Pointer): integer;

begin

  result := CompareText(TClientes(item1).Endereco, TClientes(item2).Endereco);

end;
Listagem 4. Funções de callback

As funções ClassificaPorNome e ClassificaPorEndereco serão passadas como parâmetro para o método Sort, Listagem 5.


procedure TForm1.Button2Click(Sender: TObject);

begin

  ListaClientes.Sort(@ClassificarPorEndereco);

  AtualizaListBox;

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

  ListaClientes.Sort(@ClassificaPorNome);

  AtualizaListBox;

end;
Listagem 5. Utilizando as funções de callback

Observem que não passo o nome da função e sim seu endereço na memória, isso através do operador @. Ao ser chamado, o método Sort localiza a ação a ser tomada, que por sua vez está implementada pela função passada como parâmetro.