É comum durante a programação em Delphi, encontrarmos referências aos termos TControl, TComponent, entre outros. Se você não é o tipo de programador que se dedica a escrever componentes, tais termos podem parecer totalmente sem importância.
No entanto, existe situações em que devemos ter, no mínimo, uma idéia vaga do que eles significam. Um exemplo, são os trechos de códigos que exigem cast (conversão explícita) de um tipo para outro. Vejamos o trecho de código a seguir:
procedure TForm1.Button1Click(Sender: TObject)*
var
controle: TComponent;
begin
controle := Edit1; // Edit1 é atribuido a um TComponent
(controle as TEdit).Text := 'Olá'* // De volta ao TEdit
// controle.Text := 'Olá'* // não funciona
end;
Temos uma variável controle do tipo TComponent. A linha:
controle := Edit1;
atribui a esta variável um TEdit. Esta atribuição é válida, já que TEdit descende de TComponente, como veremos mais adiante. Veja agora a linha:
(controle as TEdit).Text := 'Olá'*
Aqui o uso do operador as é obrigatório por uma razão simples: um TEdit é um TComponent, mas um TComponent não é um TEdit. Assim, o cast é nossa forma de informar ao compilador que estamos certos de que a variável controle armazena uma referência a um TEdit, e que a conversão pode ser feita sem riscos. Veja agora a última linha:
// controle.Text := 'Olá'*
Este linha não compilará, visto que um TComponent não possui as propriedades e métodos da classe TEdit. TEdit, como veremos no gráfico a seguir, descende de TWinControl.
2 - A hierarquia VCL
Um TEdit descende de TWinControl, mas, um TLabel descende de TGraphicControl. Porque? Vejamos o gráfico da hierarquia VCL:
Este gráfico nos mostra que tudo em Delphi descende de TObject. Vamos ver se é verdade. Execute o trecho de código a seguir:
procedure TForm1.Button1Click(Sender: TObject)*
begin
if Edit1 is TObject then
ShowMessage('Passou no teste')*
end;
Ao executar o código você perceberá que o teste resulta verdadeiro. Agora, respondendo a pergunta do tópico: Um TEdit descende de TCustomControl, que por sua vez descende de TWinControl. Todos os componentes que aceitam entrada do usuário ou que servem como encapsuladores para componentes visuais do Windows descendem de TWinControl. TLabel, por sua vez, descende de TGraphicControl por não receber entrada do usuário e ser considerado um controle de peso leve.
3 - TCustomEdit
Dissemos que um TEdit descende de TWinControl. Porém, é importante conhecer a classe que faz o elo entre TEdit e TWinControl. Esta classe é chamada de TCustomEdit e serve como base para todos os componentes do tipo texto e serve como ponto inicial para a criação de um TEdit personalizado, ou seja, você pode facilmente estendê-la ou simplesmente redefinir muitos de seus métodos e propriedades.
4 - Conclusão
Entender a hierarquia VCL é importante não somente para tirar o máximo proveito dos componentes que o Delphi oferece, como também escrever códigos mais compactos e robustos. E, ainda que não seja o seu objetivo, escrever componentes personalizados pode ser um passatempo muito interessante. Você também deveria tentar.
No entanto, existe situações em que devemos ter, no mínimo, uma idéia vaga do que eles significam. Um exemplo, são os trechos de códigos que exigem cast (conversão explícita) de um tipo para outro. Vejamos o trecho de código a seguir:
procedure TForm1.Button1Click(Sender: TObject)*
var
controle: TComponent;
begin
controle := Edit1; // Edit1 é atribuido a um TComponent
(controle as TEdit).Text := 'Olá'* // De volta ao TEdit
// controle.Text := 'Olá'* // não funciona
end;
Temos uma variável controle do tipo TComponent. A linha:
controle := Edit1;
atribui a esta variável um TEdit. Esta atribuição é válida, já que TEdit descende de TComponente, como veremos mais adiante. Veja agora a linha:
(controle as TEdit).Text := 'Olá'*
Aqui o uso do operador as é obrigatório por uma razão simples: um TEdit é um TComponent, mas um TComponent não é um TEdit. Assim, o cast é nossa forma de informar ao compilador que estamos certos de que a variável controle armazena uma referência a um TEdit, e que a conversão pode ser feita sem riscos. Veja agora a última linha:
// controle.Text := 'Olá'*
Este linha não compilará, visto que um TComponent não possui as propriedades e métodos da classe TEdit. TEdit, como veremos no gráfico a seguir, descende de TWinControl.
2 - A hierarquia VCL
Um TEdit descende de TWinControl, mas, um TLabel descende de TGraphicControl. Porque? Vejamos o gráfico da hierarquia VCL:
Este gráfico nos mostra que tudo em Delphi descende de TObject. Vamos ver se é verdade. Execute o trecho de código a seguir:
procedure TForm1.Button1Click(Sender: TObject)*
begin
if Edit1 is TObject then
ShowMessage('Passou no teste')*
end;
Ao executar o código você perceberá que o teste resulta verdadeiro. Agora, respondendo a pergunta do tópico: Um TEdit descende de TCustomControl, que por sua vez descende de TWinControl. Todos os componentes que aceitam entrada do usuário ou que servem como encapsuladores para componentes visuais do Windows descendem de TWinControl. TLabel, por sua vez, descende de TGraphicControl por não receber entrada do usuário e ser considerado um controle de peso leve.
3 - TCustomEdit
Dissemos que um TEdit descende de TWinControl. Porém, é importante conhecer a classe que faz o elo entre TEdit e TWinControl. Esta classe é chamada de TCustomEdit e serve como base para todos os componentes do tipo texto e serve como ponto inicial para a criação de um TEdit personalizado, ou seja, você pode facilmente estendê-la ou simplesmente redefinir muitos de seus métodos e propriedades.
4 - Conclusão
Entender a hierarquia VCL é importante não somente para tirar o máximo proveito dos componentes que o Delphi oferece, como também escrever códigos mais compactos e robustos. E, ainda que não seja o seu objetivo, escrever componentes personalizados pode ser um passatempo muito interessante. Você também deveria tentar.