A criação dinâmica de componentes em aplicações Delphi representa uma importante estratégia de desenvolvimento. Através dela os componentes são alocados dinamicamente, durante a execução do programa, e conforme a necessidade da aplicação.

Neste artigo será implementado um estudo de caso que demonstra como pode ser realizada a criação de componentes em tempo de execução (run-time).


1º Passo: desenvolvendo a aplicação Delphi
Criar uma nova aplicação no ambiente de desenvolvimento Delphi 7 através da opção do menu "File|New|Application..." e implementar o formulário principal como sugere a Figura 1.



Figura 1. Formulário principal da aplicação.

2º Passo: implementação
a) Fazer referência as unit's "Buttons" e "ExtCtrls" no início da implementation do formulário da aplicação como mostra a Listagem 1. A unit "Buttons" é necessária na manipulação do componente TBitBtn e a unit "ExtCtrls" na utilização do componente TImage.

Listagem 1. Referência as units "Buttons" e "ExtCtrls".

uses Buttons, ExtCtrls;

b) No evento "onCreate" do formulário da aplicação criar dinamicamente componentes TBitBtn, um para cada registro da tabela "events.xml" selecionada, como demonstrado na Listagem 2.

Listagem 2. Evento "onCreate" do formulário da aplicação.

procedure TForm1.FormCreate(Sender: TObject);
var ct, left, top: integer;
               bt: TBitBtn;
begin
  ClientDataSet1.Open;
  ct := 0; left := 1; top := 1;
  while (not ClientDataSet1.Eof) do
  begin
// Criando dinamicamente um componente TBitBtn
    bt := TBitBtn.Create(Self);
// Propriedade "Parent" indica que o botão criado
// será colocado sobre o objeto atual (Self = Form1)
    bt.Parent := Self;
// Associa o procedimento de evento "Janela" ao
// evento "OnClick" do botão criado
    bt.OnClick := Janela;
// Carregando a imagem do evento no botão
    bt.Glyph.Assign(ClientDataSet1.FieldByName('Event_Photo'));
    bt.Caption := ClientDataSet1.FieldByName('Event_Name').AsString;
    bt.Layout := blGlyphTop;
    bt.Height := 180;
    bt.Width := 260;
    bt.Left := left;
    bt.Top := top;
    left := left + 261;
    ct := ct + 1;
// Controla a criação de 6 botões por linha
    if (ct = 6)
       then begin
              left := 1;
              top := top + 181;
              ct := 0;
            end;
    ClientDataSet1.Next;
  end;
  ClientDataSet1.Close;
end;

c) Na interface da classe do formulário incluir o cabeçalho do procedimento de evento "Janela" como monstra a Listagem 3.

Listagem 3. Procedimento de evento "Janela" na interface da classe do formulário.

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    procedure FormCreate(Sender: TObject);
    procedure Janela(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

d) Implementar o procedimento de evento "Janela" para criar um novo formulário com a imagem do botão enviado (Sender), como apresentado na Listagem 4.

Listagem 4. Procedimento de evento "Janela".

procedure TForm1.Janela(Sender: TObject);
var fr: TForm;
    im: TImage;
begin
// Criando dinamicamente um formulário
  fr := TForm.Create(nil);
// Sender indica o objeto botão que chamou este procedimento de evento
// o operador "as" efetua o cast do objeto Sender do tipo TObject
// para tratá-lo como um objeto relacionado TBitBtn
  fr.Caption := (Sender as TBitBtn).Caption;
  fr.Position := poScreenCenter;
// Criando dinamicamente um componente TImage
  im := TImage.Create(fr);
  im.Parent := fr;
  im.Align := alClient;
  im.Center := True;
// Carregando a imagem do botão no componente TImage criado
  im.Picture.Assign((Sender as TBitBtn).Glyph);
  fr.ShowModal;
  fr.Free;
end;

Aspectos importantes da codificação apresentada:
1) O método Create é utilizado para criar uma instância da classe (aloca memória para o objeto).
2) A palavra-chave Self é usada para fazer referência ao objeto atual, aquele que é o "dono" na relação de posse.
3) Os objetos visuais, como por exemplo, os objetos criados a partir das classes TBitBtn e TImage possuem a propriedade Parent que armazena o objeto no qual eles estão contidos.
4) O parâmetro Sender representa o objeto que está chamando o procedimento de evento "Janela".
5) O operador as é utilizado para efetuar o "cast" de um objeto: (Sender as TBitBtn) trata o objeto Sender do tipo TObject como um objeto TBitBtn relacionado.

Executando a aplicação basta pressionar um botão que uma nova janela será aberta com a imagem do respectivo botão, como mostra o exemplo apresentado na Figura 2.



Figura 2. Ilustrando a execução da aplicação.

Obrigado e um abraço.

Prof. Omero Francisco Bertol (http://www.pb.utfpr.edu.br/omero/)
Download da Aplicação (http://www.pb.utfpr.edu.br/omero/Delphi/Artigos/DinamicaI.rar)