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.
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:
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
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:
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.