Olá a todos!
Tenho aulas de Delphi na faculdade esse semestre. É, meu passado me persegue! Pensei que nunca mais faria um “:=” na vida.
Um grande desafio que enfrentamos é a criação de componentes em runtime. Se o usuário quer entrar com 20 valores, devemos criar 20 textboxs para inserção dos valores, por exemplo.
Talvez não seja a maneira mais correta, mas É um jeito de trabalhar. Toda vez temos que gerar a função de novo, uma para cada tipo de componente.
Até que eu tive uma quarta feira sossegada a tarde.
Primeiro criei uma função que gerava TextBoxs no formulário. Tive algumas dificuldades, mas consegui. Me foi muito útil na prova da Matéria.
Antes de qualquer pensamento de “o diego colou”, a prova era com consulta ao material individual. Eu apenas me preparei para a guerra ;).
Dai, neste belo sábado, pensei em colar a função aqui, talvez tenha mais gente por ai com o mesmo problema. Mas passar algo tão “travado” não me deixou feliz.
Estudei um pouco sobre a “reflexão” do delphi (nesse universo com o belo nome de RunTime Type Information) e consegui deixar a função mais genérica: Agora crio qualquer tipo de componente!
Ainda estou com uma dificuldade, para o RTTI funcionar corretamente, é preciso “registrar” com antecedência as classes que você usará (TEdit, TButton, etc). Não consegui deixar isso automático.
Fica ai o código, se alguém melhorar e quiser compartilhar, será de grande utilidade para a comunidade, em minha opinião.
Função principal de criação (1/2)
function CriarComponentes ( //numero de linhas e de colunas da matriz pLinhas, pColunas : integer; //posição inicial (em px) da esquerda e topo do frm pEsquerda, pTopo : integer; //se o componente estará desabilitado ou não pEnabled : Boolean; //qual o controle pai pControlePai : TWinControl; //tipo de controle pTypeControl : String ) : Tar ; var i,j,esquerdaAux: integer; ArrayControl : TAr; //o retorno control : TClass; //classe base para criação begin //defino o tamanho do array SetLength(ArrayControl,pLinhas, pColunas); //guardamos a posição inicial da esquerda esquerdaAux := pEsquerda; //registramos as classes para poder criá-las depois (procedure auxiliar) RegistrarClasses(); control := GetClass(pTypeControl); if control = nil then begin ShowMessage('Classe não registrada! Verificar "RegistrarClasses". Interrompendo processo.'); Exit; end; for i := 0 to pLinhas - 1 do begin for j := 0 to pColunas - 1 do begin //cria o controle. Usamos o control, que agora é a classe que queremos ArrayControl[i,j] := TWinControl(TControlClass(control).Create(pControlePai)); ArrayControl[i,j].Parent := pControlePai; ArrayControl[i,j].Left := pEsquerda; ArrayControl[i,j].Top := pTopo; ArrayControl[i,j].Enabled := pEnabled; ArrayControl[i,j].Width := 25; ArrayControl[i,j].Height := 25; //descomente se quiser dar um nome ao componente... //ArrayControl[i,j].Name := 'Component'+ IntToStr(i+1+j); //vou 'mudando de coluna' Inc(pEsquerda, 30); end; //volto para a primeira coluna pEsquerda := esquerdaAux; //'mudo' de linha Inc(pTopo,30); end; //retorno o array de TWinControl Result := ArrayControl; end;
Função auxiliar para registrar classes (2/2)
procedure RegistrarClasses(); begin //para usar o GetClass, é necessário "Registrar" as classes. //se precisar alguma outra, coloque aqui. RegisterClasses([TButton, TEdit, TGroupBox]); end;
Exemplo de uso:
Coloque um botão no form e no evento de clique coloque:
procedure TForm1.Button1Click(Sender: TObject); begin MA := CriarComponentes(2,1,35,35,true,GroupBox1,TEdit.ClassName); end;
Considerações importantes
Perceba que a função retorna “TAr”. Esse é um tipo que eu defini no formulário, para poder retornar matrizes na função.
Ele retorna a matriz para que você tenha acesso a todos os componentes num ponto concentrado. As declarações ficam assim:
unit uPrincipal; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type //ESSE TIPO PRECISA SER REGISTRADO PARA RETORNAR UMA MATRIZ NUMA FUNÇÃO. TAr = array of array of TWinControl; TForm1 = class(TForm) ........ ........ var Form1: TForm1; //declaro de forma global para ter acesso MA : TAr;
Isso me permite acessar o componente criado via a matriz (MA[0,0].Propriedade, por exemplo).
Lembre-se de colocar a procedure e a function no mesmo form, a criação depende do registro.
Bom, espero que seja útil ;)
Abraços e até a próxima!
hehe delphi é pra roubar todo nosso tempo mesmo …
pensar que me recusava aprender pascal, tai um aplicativo dependendo de outro .. aff
abraço …
É Leandro, eu realmente não gosto de Delphi, mas hoje em dia parece que toda linguagem pode ser usada a qualquer momento, especialmente com SOA na área!
Hehehe, muito bom!