Bom, nesse tutorial não vou por todo o conteúdo da vídeo aula 4 pois algumas pessoas comentaram que o tutorial 3 ficou muito grande, então vou falar só sobre criação de componentes em run-time (em tempo de execução).
1) Por que criar componentes em run-time??
Vamos supor que você tenha um form que pede algumas informações do cliente mas queira que, caso esse cliente seja da cidade local (no meu caso SP), o programa peça mais informações dele, e caso seja de outra cidade, só peça para ele especificá-la.
Na figura abaixo é o Form antes do cliente especificar a cidade:
Quando o usuário seleciona o RadioButton "São Paulo" deverá aparecer um LabeledEdit (na aba Additional da paleta) para ele colocar o Endereço, como mostra a figura abaixo:
Quando o usuário seleciona o RadioButton "Outra" deverá aparecer um Edit dentro do GroupBox para ele colocar o nome da Cidade, como mostra a figura abaixo:
Mas aí você pode perguntar: Por que simplesmente não deixamos os componentes invisíveis e decidimos se mostramos ou não de acordo com os RadioButton??
Pelo consumo de memória!! O fato do componente estar invisível não quer dizer que ele não está no form. Ele ocupa um espaço na memória normalmente. Normalmente se cria componentes em run-time para otimizar uma aplicação, pois você só abre espaço de memória para o componente quando realmente for usá-lo e libera logo depois.
Agora que vocês já sabem para que serve a criação de componentes em run-time, vou explicar algumas coisas que agora pode não fazer muito sentido em termos de utilidade, mas serão necessárias no nosso programa final.
2) O Owner
Toda vez que um objeto é criado, ele tem um Owner, que é responsável pela sua liberação de memória (Free). Esse Owner é um Componente qualquer do seu projeto, normalmente o Form, e quando ele é destruido, ele se encarrega de destruir os componentes que o tem como Owner também. Quando se chama o método Create de algum componente esse Owner é o único parametro que é pedido.
Existem algums comandos especiais que podem entrar como Owner.
2.1) NIL: Se utiliza nil como Owner quando você não quer que o componente tenha um, portanto você (programador) fica responsável por liberar sua memória, a não ser que o próprio componente dê a liberdade do usuário o destruir, como os forms (simplesmente fechando-os). Portanto, normalmente se utiliza nil como Owner quando se está criando Forms.
2.2) SELF: O Self é um comando que se refere ao objeto em que o método (no caso o Create) é chamado. Note que o objeto em questão é o último Owner, ou seja, o componente "possui" todos os outros. Suponha o seguinte código, em que o Button1 cria outro botão com Owner Self:
Nesse caso o Owner do botão criado NÃO será o Button1, e sim o Form1, pois é o Form1 que possui todos esses métodos:
Viram?? Apesar do método Create estar dentro do Button1Click, o Button1Click é um MÉTODO e não o componente Button1. Ele é um método que pertence ao Form1.
3) Como o computador interpreta os gráficos
Imagine a tela do computador como um plano cartesiano. Para quem não está familiarizado com sistemas cartesiando sugiro que deem uma olhada nesse site: Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar... Tudo que você ve na tela são componentes organizados nesse plano. Mas todo plano tem um origem certo, o ponto 0x0. Normalmente estamos acostumados a trabalhar no segundo quadrante, onde a origem fica no canto inferior esquerdo, mas e o plano da tela do computador trabalha no quarto quadrante, onde a origem fica no canto superior direito da tela.
Portanto, na hora de criar qualquer objeto visual, devemos especificar onde ele irá se encontrar na tela e fazemos isso por meio de coordenadas. Se escolhermos a coordenada (0,0) a janela ficará lá no canto de cima à direita. A medida que vamos aumentando o valor do eixo Y (vertical) a janela vai descendo mais na tela. A mesma coisa acontece com o eixo X (horizontal), quanto mais aumentamos seu valor, mais pra direita vai ficar a janela. Note que no meu exemplo, se o valor da coordenada do eixo Y for maior que 1080, por exemplo (0,2000), a janela não será mais visível, pois minha tela tem apenas 1080 pixels.
5) Parent
Como descrito no tópico acima, é necessário colocar as coordenadas do componente mas, não necessariamente em relação à tela. Podemos colocar as coordenadas em relação a outro componente, por exemplo um GroupBox. Se criarmos um botão e definirmos como seu Parent um GroupBox, a coordenada (0,0) sera no canto superior direito do Groupbox, e não da tela. Vamos ver um exemplo, o código abaixo cria um botão com o Form1 como Owner na coordenada (0,0) do GroupBox. Note que o Delphi se refere ao eixo Y como "Top" e ao eixo X como "Left".
6) Definindo as propriedades do componente
Bom, vocês já sabem quase tudo para a criação de componentes em run-time, só falta a definição das propriedades dele. Notem que eu utilizei um método no tópico acima para explicar o parent, mas vou explicar agora.
Basicamente, você deve criar uma variável do tipo do componente que deseja criar, um TButton por exemplo. Depois deve jogar na variável o componente criado e depois é só definir os parametros, como no seguinte código:
A diferença é que eu fiz tudo de uma vez utilizando o with/do. Agora só falta uma coisa para vocês conseguirem fazer uma criação de componentes completa. Como eu adiciono um evento no componente??
Bom, para adicionar um evento num componente criado, primeiro é necessário criar a rotina para esse evento. Por exemplo, vamos criar uma rotina para o evento onClick do nosso botão. Para isso deve-se lembrar que a rotina em si não pertence ao botão e sim ao Owner do botão, que no caso é o Form1 (é a mesma coisa que discutimos no comando Self). Então vamos declarar uma procedure chamada "MeuBotaoClick", que recebe os mesmos parametros que o onClick de um botão, pertencente ao Form1. Para isso devemos adicioná-la como mostra a figura abaixo:
Agora falta escrevermos a procedure certo?? Vamos fazê-la mostrar uma simples mensagem. Como ela pertence ao Form1, devemos indicar isso na hora de escrevê-la:
Agora é só fazer o onClick do botão receber a procedure MeuBotaoClick na hora de definir os parametros.
7) Is, As e Sender
Bom, haverá algum momento em que vocês vão precisar fazer verificações e modificações de componentes em run-time, para isso utilizarão os comandos IS, AS e Sender. O comando IS é muito fácil de entender, ele simplesmente checa se o componente pertence à uma tal classe. Por exemplo vamos testar se o Button1 pertence a Classe TButton e depois à classe TEdit. Sim, o resultado é óbvio, mas o importante é entender como se usa o IS.
O comando AS é usado para "casting", ou seja, para especificar uma classe a um componente. Vamos fazer uma rotina para verificar se existe um botão com o caption "Button1" no Form1.
Note que não podemos utilizar Form1.Components[i].Caption pois o Parametro Caption não é da classe TComponent e sim da TButton, entre outras.
Sender se referencia ao componente utilizado para chamar aquela rotina, por exemplo o onClick de um botão. O componente usado para chamar a rotina foi o Button1, então no seu onClick o comando Sender irá se referenciar a ele. Vamos fazer uma rotina que cria 5 botões e faz cada um mostrar uma mensagem contendo seu nome.
Não esquecam de declarar BotoesClick como uma rotina pertencente ao Form1. Vejam o resultado!!
Pronto, basicamente é assim que se cria componentes em run-time. Por acaso ainda se lembram do exemplo do cadastro de clientes que dei acima?? Vou deixar o source disponível para vocês baixarem e darem uma olhada. Com esse tutorial vocês serão capazes de entedê-lo perfeitamente.
Créditos: Ace Ventura
1) Por que criar componentes em run-time??
Vamos supor que você tenha um form que pede algumas informações do cliente mas queira que, caso esse cliente seja da cidade local (no meu caso SP), o programa peça mais informações dele, e caso seja de outra cidade, só peça para ele especificá-la.
Na figura abaixo é o Form antes do cliente especificar a cidade:
Quando o usuário seleciona o RadioButton "São Paulo" deverá aparecer um LabeledEdit (na aba Additional da paleta) para ele colocar o Endereço, como mostra a figura abaixo:
Quando o usuário seleciona o RadioButton "Outra" deverá aparecer um Edit dentro do GroupBox para ele colocar o nome da Cidade, como mostra a figura abaixo:
Mas aí você pode perguntar: Por que simplesmente não deixamos os componentes invisíveis e decidimos se mostramos ou não de acordo com os RadioButton??
Pelo consumo de memória!! O fato do componente estar invisível não quer dizer que ele não está no form. Ele ocupa um espaço na memória normalmente. Normalmente se cria componentes em run-time para otimizar uma aplicação, pois você só abre espaço de memória para o componente quando realmente for usá-lo e libera logo depois.
Agora que vocês já sabem para que serve a criação de componentes em run-time, vou explicar algumas coisas que agora pode não fazer muito sentido em termos de utilidade, mas serão necessárias no nosso programa final.
2) O Owner
Toda vez que um objeto é criado, ele tem um Owner, que é responsável pela sua liberação de memória (Free). Esse Owner é um Componente qualquer do seu projeto, normalmente o Form, e quando ele é destruido, ele se encarrega de destruir os componentes que o tem como Owner também. Quando se chama o método Create de algum componente esse Owner é o único parametro que é pedido.
Existem algums comandos especiais que podem entrar como Owner.
2.1) NIL: Se utiliza nil como Owner quando você não quer que o componente tenha um, portanto você (programador) fica responsável por liberar sua memória, a não ser que o próprio componente dê a liberdade do usuário o destruir, como os forms (simplesmente fechando-os). Portanto, normalmente se utiliza nil como Owner quando se está criando Forms.
2.2) SELF: O Self é um comando que se refere ao objeto em que o método (no caso o Create) é chamado. Note que o objeto em questão é o último Owner, ou seja, o componente "possui" todos os outros. Suponha o seguinte código, em que o Button1 cria outro botão com Owner Self:
Código:
procedure TForm1.Button1Click(Sender: TObject); begin TButton.Create(Self); end;
Viram?? Apesar do método Create estar dentro do Button1Click, o Button1Click é um MÉTODO e não o componente Button1. Ele é um método que pertence ao Form1.
3) Como o computador interpreta os gráficos
Imagine a tela do computador como um plano cartesiano. Para quem não está familiarizado com sistemas cartesiando sugiro que deem uma olhada nesse site: Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar... Tudo que você ve na tela são componentes organizados nesse plano. Mas todo plano tem um origem certo, o ponto 0x0. Normalmente estamos acostumados a trabalhar no segundo quadrante, onde a origem fica no canto inferior esquerdo, mas e o plano da tela do computador trabalha no quarto quadrante, onde a origem fica no canto superior direito da tela.
Portanto, na hora de criar qualquer objeto visual, devemos especificar onde ele irá se encontrar na tela e fazemos isso por meio de coordenadas. Se escolhermos a coordenada (0,0) a janela ficará lá no canto de cima à direita. A medida que vamos aumentando o valor do eixo Y (vertical) a janela vai descendo mais na tela. A mesma coisa acontece com o eixo X (horizontal), quanto mais aumentamos seu valor, mais pra direita vai ficar a janela. Note que no meu exemplo, se o valor da coordenada do eixo Y for maior que 1080, por exemplo (0,2000), a janela não será mais visível, pois minha tela tem apenas 1080 pixels.
5) Parent
Como descrito no tópico acima, é necessário colocar as coordenadas do componente mas, não necessariamente em relação à tela. Podemos colocar as coordenadas em relação a outro componente, por exemplo um GroupBox. Se criarmos um botão e definirmos como seu Parent um GroupBox, a coordenada (0,0) sera no canto superior direito do Groupbox, e não da tela. Vamos ver um exemplo, o código abaixo cria um botão com o Form1 como Owner na coordenada (0,0) do GroupBox. Note que o Delphi se refere ao eixo Y como "Top" e ao eixo X como "Left".
Código:
procedure TForm1.Button1Click(Sender: TObject); begin with TButton.Create(Self) do begin Caption:='Meu botao'; Parent:=GroupBox1; Top:=0; Left:=0; end; end;
6) Definindo as propriedades do componente
Bom, vocês já sabem quase tudo para a criação de componentes em run-time, só falta a definição das propriedades dele. Notem que eu utilizei um método no tópico acima para explicar o parent, mas vou explicar agora.
Basicamente, você deve criar uma variável do tipo do componente que deseja criar, um TButton por exemplo. Depois deve jogar na variável o componente criado e depois é só definir os parametros, como no seguinte código:
Código:
procedure TForm1.Button1Click(Sender: TObject); var b: TButton; begin b:=TButton.Create(Self); b.Caption:='Meu botao'; b.Parent:=GroupBox1; b.Top:=0; b.Left:=0; end;
Bom, para adicionar um evento num componente criado, primeiro é necessário criar a rotina para esse evento. Por exemplo, vamos criar uma rotina para o evento onClick do nosso botão. Para isso deve-se lembrar que a rotina em si não pertence ao botão e sim ao Owner do botão, que no caso é o Form1 (é a mesma coisa que discutimos no comando Self). Então vamos declarar uma procedure chamada "MeuBotaoClick", que recebe os mesmos parametros que o onClick de um botão, pertencente ao Form1. Para isso devemos adicioná-la como mostra a figura abaixo:
Agora falta escrevermos a procedure certo?? Vamos fazê-la mostrar uma simples mensagem. Como ela pertence ao Form1, devemos indicar isso na hora de escrevê-la:
Código:
procedure TForm1.MeuBotaoClick(Sender: TObject); begin Showmessage('Chmod esta de volta!!'); end;
Código:
procedure TForm1.Button1Click(Sender: TObject); begin with TButton.Create(Self) do begin Caption:='Meu botao'; Parent:=Form1; Top:=0; Left:=0; OnClick:=MeuBotaoClick; end; end;
7) Is, As e Sender
Bom, haverá algum momento em que vocês vão precisar fazer verificações e modificações de componentes em run-time, para isso utilizarão os comandos IS, AS e Sender. O comando IS é muito fácil de entender, ele simplesmente checa se o componente pertence à uma tal classe. Por exemplo vamos testar se o Button1 pertence a Classe TButton e depois à classe TEdit. Sim, o resultado é óbvio, mas o importante é entender como se usa o IS.
Código:
procedure TForm1.Button1Click(Sender: TObject); begin if Button1 is TButton then showmessage('Pertence à classe TButton'); end;
Código:
procedure TForm1.Button1Click(Sender: TObject); begin if Button1 is TEditthen showmessage('Pertence à classe TEdit') else Showmessage('Não pertence à classe TEdit'); end;
Código:
function Verifica: boolean; var Comp: TComponent; i: integer; begin Result:=False; for i:=0 to Form1.ComponentCount-1 do begin if Form1.Components[i] is TButton then begin if (Form1.Components[i] as TButton).Caption= 'Button1' then begin Result:=True; exit; end; end; end; end;
Sender se referencia ao componente utilizado para chamar aquela rotina, por exemplo o onClick de um botão. O componente usado para chamar a rotina foi o Button1, então no seu onClick o comando Sender irá se referenciar a ele. Vamos fazer uma rotina que cria 5 botões e faz cada um mostrar uma mensagem contendo seu nome.
Código:
procedure TForm1.BotoesClick(Sender: TObject); begin Showmessage((Sender as TButton).Name); end; procedure TForm1.FormCreate(Sender: TObject); var i: integer; begin for i:=1 to 5 do begin with TButton.Create(Self) do begin Parent:=Form1; Top:=(Height + 10) * i; Left:=10; Name:='Botao' + inttostr(i); OnClick:=BotoesClick; end; end; end;
Pronto, basicamente é assim que se cria componentes em run-time. Por acaso ainda se lembram do exemplo do cadastro de clientes que dei acima?? Vou deixar o source disponível para vocês baixarem e darem uma olhada. Com esse tutorial vocês serão capazes de entedê-lo perfeitamente.
Créditos: Ace Ventura