Centralizando rotinas em uma unit
João Alberto Licht Teixeira
Qual desenvolvedor ainda não se deparou com a crueldade de ficar repetindo código e mais código em vários componentes diferentes, mas que basicamente fará a mesma coisa, como por exemplo, mudar a cor quando eles receberem e perderem foco?
A tendência é colocar código em cada evento OnEnter e OnExit, o que deixaria o código enorme e nada elegante quando tivéssemos algumas dezenas ou até centenas de componentes que devessem obedecer esse tratamento de foco.
Para resolver o problema, a idéia é concentrar o trabalho pesado em uma rotina, que por sua vez ficará dentro de uma unit que possa ser utilizada (via uses) em qualquer lugar da aplicação.
Conteúdo da rotina
A rotina deverá receber o formulário que a está chamando como parâmetro, para que apenas os componentes desse formulário recebam tratamento. A aparência seria semelhante à da (Figura 1), logicamente com a cor que o desenvolvedor ou até mesmo o usuário tivesse escolhido – mas isso é coisa pra outro artigo.
Figura 1. Aparência dos Edits com e sem foco
Abaixo está o código da função, que está residente na unit U_Global, mas que pode ser qualquer uma de sua escolha. (veja a Listagem 1).
Listagem 1. Função TrataFoco
unit U_Global;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs, DBCtrls;
procedure TrataFoco(Forma: TFormClass);
implementation
procedure TrataFoco(Forma: TFormClass);
var
C : Word;
I : Integer;
ABC : TForm;
Const
ComFoco = TColor(clSkyBlue);
SemFoco = TColor(clWhite);
begin
for I := 0 To Screen.FormCount - 1 do
begin
ABC := Screen.Forms[I];
if ABC.ClassType = Forma then
for C := 0 to Screen.Forms[I].ComponentCount - 1 do
begin
// -------------
// Com Foco
// -------------
if (Screen.Forms[I].Components[C] is TEdit) and
(Screen.Forms[I].Components[C] as TEdit).Focused then
(Screen.Forms[I].Components[C] as TEdit).Color := ComFoco;
if (Screen.Forms[I].Components[C] is TDBEdit) and
(Screen.Forms[I].Components[C] as TDBEdit).Focused then
(Screen.Forms[I].Components[C] as TDBEdit).Color := ComFoco;
. . .
// Aqui deverão ser adicionados todos os componentes que deverão ter o foco tratado
. . .
// -------------
// Sem focado
// -------------
if (Screen.Forms[I].Components[C] is TEdit) and
not(Screen.Forms[I].Components[C] as TEdit).Focused then
(Screen.Forms[I].Components[C] as TEdit).Color := SemFoco;
if (Screen.Forms[I].Components[C] is TDBEdit) and
not(Screen.Forms[I].Components[C] as TDBEdit).Focused and
(Screen.Forms[I].Components[C] as TDBEdit).Enabled then
(Screen.Forms[I].Components[C] as TDBEdit).Color := SemFoco;
end;
end;
end;
end.
Explicando o código
É feita uma varredura em todos os forms da aplicação para saber qual form (parametrizado em Forma) a função está tratando, quando então será feita uma varredura em todos os componentes desse form (Forma) e, se eles estiverem referenciados dentro da função, terão então suas cores tratadas. Lembre-se de que o mesmo componente deverá ter as linhas de código para tratamento de quando estiver COM e SEM foco dentro da mesma função.
As constantes ComFoco e SemFoco, do tipo TColor, encarregam-se de colorir o componente que receber ou perder o foco.
Utilizando o código
Para disparar o código, utiliza-se um TTimer (System), que deve ter sua propriedade Interval = 1 e o código da Listagem 2 no seu evento OnTimer, em cada formulário que terá o foco de seus componentes tratado:
Listagem 2.
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
TrataFoco(TForm1);
Timer1.Enabled := True;
end;
Conclusões
Com a maneira centralizada que está sendo proposta, basta você utilizar a criatividade para viabilizar o tratamento global de muitas outras propriedades e eventos em seu aplicativo, de forma limpa, clara e rápida.
João Alberto Licht Teixeira (joão@solespe.com.br) é programador, instrutor e desenvolvedor Delphi desde a versão 1. É sócio proprietário da Solespe Informática Ltda (www.solespe.com.br) de Santa Maria - RS, trabalha com MySQL em projetos cliente/servidor e multicamadas.