22 de abril de 2010

Criando componentes com Delphi - parte II

Para mostrar os conceitos mais básicos por trás da criação de componentes no Delphi eu vou usar um exemplo bastante simples. Esse primeiro componente servirá apenas para forçar que a altura e o comprimento de um botão sejam mantidos num valor fixo. O objetivo é que estas propriedades do botão fiquem automaticamente padronizadas, sem possibilidade de que o programador possa alterá-las quando estiver desenhando uma tela. Essa técnica permite que se estabeleçam padrões visuais a serem compartilhados por todas as telas de um programa, que manterá uma identidade visual coesa. Mudar algum dos padrões seria, então, questão de mudar internamente um único componente !

Ok ! Esse mesmo objetivo pode ser atingido clicando-se com o botão direito num componente e escolhendo-se o comando Add To Palete. Mas esse procedimento esconde alguns dos conceitos que eu gostaria de mostrar.

De início, vou criar um novo pacote para incluir o componente e assim poder distribuí-lo junto com as aplicações - ou para que outros desenvolvedores possam criar suas aplicações. A compilação de um pacote no Delphi (e C++ Builder) gera uma arquivo com extensão BPL que é na verdade uma DLL com algumas particularidades.
Pacote
Neste exemplo, a mesma biblioteca BPL será usada tanto em design time (ambiente de desenvolvimento) quanto em runtime (tem que estar presente quando for executar as aplicações).

Agora que já temos o pacote que servirá de container ao nosso componente, podemos criar-lhe o esqueleto. Na minha versão do Delphi (2005), isso pode ser feito através do menu Component, opção New VCL Component. A seguir, é apresentado um wizard onde se pode escolher a classe que servirá de base para o componente. Como já existe um componente com toda a funcionalidade do botão, vou usá-lo como base para não ter que reinventar a roda. Após informar o nome para o novo componente, é criada uma unit com o básico a respeito do componente:
TWButtonModelo = class(TButton)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;

{ ... }

procedure Register;
begin
RegisterComponents('Samples', [TWButtonModelo]);
end;

A procedure Register é criada automaticamente e representa uma parte importante do processo de fazer o IDE do Delphi enxergar o componente. Quando solicitamos ao IDE que faça a instalação de um pacote BPL, ele procurará dentro da biblioteca a função Register de cada unit e as executará. Como resultado, os componentes existentes no pacote passarão a ficar disponíveis na paleta de componentes do IDE, podendo então ser usado pelo programador em qualquer form.

Veja que no esqueleto gerado para a classe do componente há uma seção chamada Published. As propriedades que forem incluídas nessa seção poderão ser modificadas pelo programador em design time já que elas aparecerão no Inspector do Delphi quando o nosso componente estiver selecionado. Do ponto de vista das restrições de acesso por outras áreas do programa, propriedades published funcionam exatamente da mesma maneira que aquelas na seção Public, isto é, são sempre visíveis para as demais units.

Pra terminar esse exemplo básico, falta apenas restringir a mudança de valores de altura e comprimento, que é o comportamento proposto. Há uma função chamada SetBounds introduzida na classe TControl que é responsável pelas alterações relativas a posicionamento e dimensões de todos os controles. Como ela é declarada como virtual, vou apenas sobrepô-la e forçar os tamanhos que eu quero:
procedure TWButtonModelo.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
AWidth := 80;
AHeight := 28;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
Essa função é chamada mesmo que se modifique o valor de uma única propriedade relacionada ao tamanho do componente. Isto é, se você tentar modificar a altura ou o comprimento separadamente, ainda assim a função é chamada e forçará os valores fixados dentro do componente.

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.