Trabalhando com as classes do Delphi

Autor: Robert Gaffo - rgaffo@gmail.com

Robert Gaffo é programador Delphi e instrutor de programação em Delphi e outras linguagens como Visual Basic, C/C++ e Java. Leciona aulas de conceitos de Banco de Dados, SQL Server, Oracle, Interbase/Firebird e MySql e dá treinamentos In Company. Trabalha com Delphi em aplicações desktop e multi-camadas.

Objetivos:

- Conhecer a hierarquia das classes.
- Como usá-las.
- Entender como elas podem ser úteis para facilitar nosso trabalho.
- Identificar as classes dos objetos.

Olá pessoal do iMasters. Primeiramente quero agradecer a oportunidade que me foi dada para que eu possa passar a vocês um pouco do que eu conheço e ajudá-los ao máximo na programação Delphi.

Nessa primeira coluna gostaria de mostrar para vocês como usar as classes do Delphi para facilitar a nossa programação. Espero que tirem muito proveito e que essa seja a primeira de muitas outras colunas que teremos aqui. Fiquem a vontade para mandar e-mails, tirar dúvidas e dar sugestões.

Hierarquia das classes

Entender a hierarquia das classes no Delphi nos ajudará a entender, por exemplo, como generalizar vários objetos (Buttons, Edits, Labels e etc...) como se eles fossem um só, desde que tenham em comum as propriedades que queremos usar para fazer algum tipo de manipulação.

 

image001.gif

 

TObject é a Classe de origem de todos os objetos da VCL e componentes.

TPersistent é a Classe de origem de todos os objetos que podem ser associados para outros e que podem ler e escrever propriedades.

TComponent é a Classe de origem de todos os objetos da VCL. Permite que a classe apareça na paleta de componentes.

TControl é a Classe de origem todos os componentes que são visíveis em Run-Time.

TWinControl é a Classe de origem de todos componentes que recebem foco, tem Handle1 e que são containers2 de outros objetos. Ex.: TPanel, TEdit, TGroupbox, TListbox e etc…

TGraphicControl é a Classe de origem de todos os componentes que são não recebem foco, não tem Handle e que não são containers para outros objetos. Ex.: TBevel, TImage, TShape, TSpeedButton e etc…

Essa é a descrição básica para cada tipo das Classes principais usadas no Delphi. A partir desse conceito veremos a aplicação prática das classes.

Como usá-las

Primeiro exemplo: Mudando a cor dos DBEdits

Temos um formulário para cadastro de clientes como esse:

image002.gif

Se quisermos, por exemplo, implementar um recurso que, quando o usuário selecione um campo, mude a cor do fundo do DBEdit ou somente as propriedades de fonte dele. Muitos fariam assim:

procedure TfrmCustomer.DBEdit1Enter(Sender: TObject);
begin
DBEdit1.Color := clYellow;
end;

procedure TfrmCustomer.DBEdit1Exit(Sender: TObject);
begin
DBEdit1.Color := clWhite;
end;

Isso é para um campo, então teríamos que repetir o código para todos os outros campos para então manter um padrão, certo. Mas, podemos resolver esse problema com somente 2 linhas de comandos: uma para quando o objeto ganhar o foco e outro quando perder o foco.

Sabemos que todos os objetos que desejamos usar esse recurso é um DBEdit. Então generalizaremos todos os DBEdit usando sua classe que é TDBEdit. TDBEdit é descendente indireto3 de TwinControl. Então fazemos assim agora:

procedure TfrmCustomer.DBEdit1Enter(Sender: TObject);
begin
TDBEdit(Sender).Color := clYellow;
end;

procedure TfrmCustomer.DBEdit1Exit(Sender: TObject);
begin
TDBEdit(Sender).Color := clWhite;
end;

Entendendo o código:

O parâmetro Sender que tem na procedure se refere ao objeto que chamou a procedure. Ou seja, quando você colocar o foco no campo FIRST_NAME por exemplo, será chamado o evento OnEnter desse objeto, então Sender passa ser o nome do DBEdit referente ao campo FIRST_NAME. Dessa forma fazemos um casting4 do parâmetro Sender para DBEdit, daí nós podemos usar todas as propriedades do DBEdit e fazer o que quiser com o objeto passado no parâmetro Sender.

Associando com os outros DBEdits

Depois de fazer isso para um DBEdit, selecionamos todos os outros e vamos até a aba de eventos no Object inspector. Procure por OnEnter e escolha a procedure do DBEdit que você acabou de digitar referente ao evento OnEnter. Agora, no evento OnExit, escolha a procedure do DBEdit referente ao evento OnExit. Dessa forma associamos todos os objetos DBEdit à mesma procedure que é a do campo EMP_NO. A partir daí a procedure trata cada objeto como se tivéssemos digitado o código para cada um dos DBEDits.

Segundo Exemplo: Mudando o foco ao pressionar Enter

Usando o mesmo projeto, vamos implementar um código para que. ao pressionar o enter, o foco vá para o próximo controle. Muitos fariam assim:

procedure TfrmCustomer.DBEdit1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #13) then
DBEdit2.setfocus;
end;

procedure TfrmCustomer.DBEdit2KeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #13) then
DBEdit3.setfocus;
end;

E assim por diante, podemos também generalizar esse código para que digitemos para um DBEdit e todos reflitam o mesmo.

procedure TfrmCustomer.DBEdit1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #13) then
SelectNext(TWinControl(Sender), True, True);
end;

Agora associe os outros DBEdits no evento OnKeyPress dos outros DBEdits. Escolha a procedure referente ao OnKeyPress do DBEdit1 que você acabou de digitar.

Note que agora usamos a classe TwinControl, que é a classe base de todos os objetos que recebem foco. Logo, não precisamos associar esse evento somente com OnKeyPress, mas com todos os objetos que podem receber foco.

Terceiro Exemplo: Limpando o valor de todos os Edits

image003.gif

Vamos supor que montamos um programa como esse, bem simples, poucos recursos. O que importa para nós nesse caso é o botão Limpar. A função dele é apagar os valores de todos os Edits, isso é fácil. Faríamos assim:

procedure TForm1.Button5Click(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
Edit3.Clear;
end;

Sem maiores complicações, não é? Mas podemos fazer assim:

procedure TForm1.Button5Click(Sender: TObject);
var
i : Word;
begin
for i := 0 to ComponentCount - 1 do
if (Components[i] is TEdit) then
TEdit(Components[i]).Clear
end;

Entendendo o código

Declaramos um contador “i”, criamos um looping de 0 até ComponentCount5 – 1, depois perguntamos se o componente do formulário que está na posição “i” (Components[i]) pertence à classe TEdit. Se pertencer, então fazemos um casting do componente, que está nesse índice e apagamos seu valor.

Dai vocês argumentam, mas código é complicado e extenso por pouca coisa. Concordo, mas se tivermos 10 ou até mesmo 15 Edits? Esse código vale para todos eles, não mudando nada para isso.

Esse código não é só para tratar o Edit. Pode ser utilizado para outras validações com outros objetos também.

Conclusão:

Podemos usar as classes já implementadas no Delphi, e facilitar e muito no desenvolvimento dos nossos programas, e até mesmo criar nossos próprios componentes ou objetos, aumentando assim a produtividade e facilidade de entender o código. Espero que essa coluna ajude a muitos de vocês, ou senão, que tenha aberto outros caminhos. Abraços, até a próxima.

Baixar os fontes:

Fonte 1
Fonte 2

Notas:

1 Handle é uma identificação que o windows dá a um objeto ou uma janela quando é criada.

2 Containers são objetos que podem ter outros objetos dentro dele, como o Panel, TabSheet, Groupbox entre outros.

3 Indireto por que existem outras classes entre TWinControl e TDBEdit.

4 Casting nome dado quando você converter um tipo em outro, no caso convertemos o parâmetro Sender que é do tipo TObject para TDBEdit para fazermos a manipulação das propriedades do DBEdit.

5 ComponentCount retorna a quantidade de componentes no formulário atual, assim podemos varrer todos os componentes do form usando Components[Num], onde Num é o índice do objeto a quem estamos nos referenciando.