<< Click to Display Table of Contents >> Funções de CallBack |
![]() ![]() ![]() |
Callback Procedures
Resumidamente, uma função de callback é uma rotina em seu programa que uma biblioteca chama.
Um callback é um modo de enviar uma função como um parâmetro dentro de uma outra função.
Quando a função de callback completa, o controle é passado de volta à função original.
Nós nunca chamamos uma função de callback diretamente; a função da biblioteca chama ela por nós.
Sim, é uma loucura. Se você ver o exemplo abaixo, vai entender. Ou não. :|
Exemplo 1 - uso simples
unit ExemploUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMeuForm = class(TForm)
OKBtn: TButton;
NomeEdit: TEdit;
procedure OKBtnClick(Sender: TObject);
private
procedure MinhaFuncaoLocal;
end;
var
MeuForm: TMeuForm;
implementation
{$R *.dfm}
// primeiro passo é DENTRO DA BIBLIOTECA, precisamos declarar um tipo para passar ele como
// parâmetro para nossa função. Neste exemplo criamos um tipo chamado TRotinaCallback:
type
TRotinaCallBack = procedure of object;
// esta aqui é a função que está na nossa biblioteca (neste exemplo é a rotina InformaAbort que fica
// nos subterrâneos da mLib, note que o ultimo parâmetro (opcional) é do tipo TRotinaCallBack
procedure InformaAbort(const Condicao: Boolean; const Texto: string; Foco: TWinControl = nil; Rotina: TRotinaCallBack = nil);
begin
// se a condição for falsa já cai fora
if not Condicao then
Exit;
// mostra um alerta
ShowMessage(Texto);
// chama nossa rotina de callback (se estiver associada)
if Assigned(Rotina) then
Rotina;
// manda o foco para o componente
TWinControl(Foco).SetFocus;
// manda um abort
SysUtils.Abort;
end;
// para usar esta 8ª maravilha da programação, é bem simples, basta no seu projeto declarar uma função
// igual a do tipo TRotinaCallBack (neste exemplo a nossa NÃO POSSUI parametros):
procedure TMeuForm.MinhaFuncaoLocal;
begin
// passa a cor do form para vermelho
Color := clRed;
end;
// aqui no clique do botão, chamamos a função da mLib InformaAbort, sendo que passamos nossa função local
// como parâmetro para ela, a InformaAbort irá de dentro da lib chamar nossa função que se encontra
// no form. Entendeu?
procedure TMeuForm.OKBtnClick(Sender: TObject);
begin
InformaAbort(True, 'Deu erro', NomeEdit, MinhaFuncaoLocal);
end;
end.
Exemplo 2 - uso de parâmetros
unit Unit6;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMeuForm = class(TForm)
OKBtn: TButton;
NomeEdit: TEdit;
procedure OKBtnClick(Sender: TObject);
private
procedure MinhaFuncaoLocal(const MsgSecreta: string);
end;
var
MeuForm: TMeuForm;
implementation
{$R *.dfm}
// Não esqueça que a declaração deve ser a mesma da rotina no seu fonte:
type
TRotinaCallBack = procedure(const MensagemUpper: string) of object;
// esta aqui é a função que está na nossa biblioteca (neste exemplo é a rotina InformaAbort que fica
// nos subterrâneos da mLib, note que o ultimo parâmetro (opcional) é do tipo TRotinaCallBack
procedure InformaAbort(const Condicao: Boolean; const Texto: string; Foco: TWinControl = nil; Rotina: TRotinaCallBack = nil);
begin
if not Condicao then
Exit;
ShowMessage(Texto);
if Assigned(Rotina) then
Rotina(AnsiUpperCase(Texto)); // veja que aqui eu passo um parâmetro para a função!
TWinControl(Foco).SetFocus;
SysUtils.Abort;
end;
procedure TMeuForm.MinhaFuncaoLocal(const MsgSecreta: string);
begin
// exibe a mensagem vinda da função InformaAbort!
ShowMessage(MsgSecreta);
end;
procedure TMeuForm.OKBtnClick(Sender: TObject);
begin
InformaAbort(True, 'esta mensagem foi escrita originalmente em minúscula', NomeEdit, MinhaFuncaoLocal);
end;
end.