6 de maio de 2010

Criando componentes com Delphi - parte III

Uma técnica também bastante utilizada para criar novos componentes é fazer uma combinação de outros já existentes e publicar o conjunto como se fosse um só, selecionando propriedades e eventos relevantes para incluir no Object Inspector do Delphi e escondendo outros conforme a necessidade.

Na ABC71, por exemplo, temos um componente "lookup" cujo objetivo é permitir ao usuário digitar um valor qualquer - se ele souber de cabeça um código, a digitação se torna mais rápida - ou escolher um dos valores válidos através da consulta a uma lista. O significado do código é uma das propriedades do componente, podendo ser Cliente, Produtos, Pedidos, Títulos, etc. É exibido ao usuário uma caixa de edição para digitação do código, um botão para acionar a lista (quando for preciso) e outra caixa que exibe uma descrição para o código informado na primeira caixa.

Vou montar um componente mais simples para ilustrar essa técnica, colocando uma caixa de edição para o usuário informar um caminho completo de arquivo e um botão caso ele prefira selecionar visualmente o arquivo desejado. Ao sair da caixa de edição, o programador terá a oportunidade de validar o conteúdo informado através de um evento que criaremos. Algumas propriedades a serem publicadas: o texto inicial para a caixa de edição; se o arquivo informado deve existir ou não; quais máscaras de arquivos poderão ser aceitas; etc.

A primeira decisão a ser tomada é em relação à qual classe deve ser usada como base para o componente. Dado que ele permitirá interações com o usuário, devemo usar TControl ou uma de suas heranças, como o TWinControl. A diferença entre ambos é que o TWinControl encapsula a funcionalidade de uma janela, ou seja, pode, entre outras coisas, receber o foco, receber entrada de dados através do mouse ou do teclado, tratar mensagens do Windows (WM_PAINT, por exemplo). Nosso componente será composto por uma caixa de edição e um botão, que já têm todos esses recursos; por isso, o componente em si não precisará implementá-los. No entanto, esses componentes só são visíveis quando a propriedade Parent é informada - obrigatoriamente um TWinControl. Se quisermos que nosso componente seja o Parent dos que forem adicionados internamente, teremos que criá-lo como um TWinControl.
type
TWSelecionaArq = class(TWinControl)
private
_Edit : TEdit;
_Btn : TBitBtn;
_OpenDialog: TOpenDialog;

{ ... }

constructor TWSelecionaArq.Create(AOwner: TComponent);
begin
inherited;

_Edit := TEdit.Create (Self);
_Edit.Parent := Self;

_Btn := TBitBtn.Create (Self);
_Btn.Parent := Self;
_Btn.OnClick := SelecionarArquivo;
_Btn.SetBounds (0, 0, 28, 25);

{ ... }

_OpenDialog := TOpenDialog.Create (Self);

SetBounds (Left, Top, 200, 0);
{ ... }
O excerto acima mostra ainda a declaração dos membros internos da classe que representam o botão e a caixa de edição. Também mostra um TOpenDialog que será usado para exibir a caixa de diálogo que permitirá ao usuário final selecionar um arquivo.

No trecho relativo ao construtor, os componentes internos são criados e o Parent de cada um é ajustado para nosso próprio componente (self), responsável por exibí-los. Note que nada é feito para posicionar corretamente os componentes internos. Isto mais uma vez será feito pela função SetBounds, que é chamada sempre que o posicionamento ou tamanho de nosso componente é alterado :

procedure TWSelecionaArq.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
{ Altura do componente é a mesma do botão }
AHeight := _Btn.Height + 2;
{ Comprimento mínimo do componente }
if AWidth < 200 then
AWidth := 200;

{ posiciona o edit e o botão }
_Edit.Width := AWidth - _Btn.Width;
_Btn.Left := _Edit.Width + 1;

{ ajuste dos tamanhos do componente }
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;

Com o esqueleto do componente pronto, podemos acrescentar declarações para as propriedades e eventos desejados. Volto no próximo post com esses detalhes da implementação.

Mais Informações
Criando componentes com Delphi - parte I e parte II

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.