Class Helpers no Delphi: Modificando componentes da VCL

Veja neste artigo como modificar o comportamento padrão de componentes visuais do Delphi utilizando o recurso de Class Helpers.

Motivação

Durante o desenvolvimento de aplicações Delphi é comum a necessidade de adicionar aos componentes visuais algumas funcionalidades extras, como validação e formatação de dados. Para atender a esse tipo de situação, alguns programadores optam por utilizar herança, enquanto outros alteram diretamente o código fonte do componente. Essas, porém, não são as melhores soluções, pois a herança obriga a utilização de uma nova classe, ao invés do componente padrão, e a alteração do código fonte pode gerar problemas em outras partes do sistema que utilizem esse mesmo componente.

A fim de suprir essa demanda, a partir da versão 2006 o Delphi passou a contar com um recurso chamado Class Helper, tornando possível adicionar novos comportamentos aos componentes sem usar herança ou modificar o código fonte original.

Saiba mais sobre a série de cursos sobre Delphi

Definição

No Delphi, Class Helper é um recurso que permite adicionar métodos e modificar comportamentos de componentes em tempo de execução, sem a necessidade de herdar a classe ou utilizar recursos de composição, fazendo parecer que a classe contém o novo comportamento desde sua criação.

Outro diferencial é que Class Helpers não se aplicam somente a componentes. Eles também permitem modificar classes de domínio criadas pelo desenvolvedor, adicionar métodos a estruturas do tipo record e tipos primitivos (introduzidos a partir da versão XE3). Nesse último caso, no entanto, não é possível adicionar propriedades.

Como criar

Na Listagem 1 é apresentada uma unit que implementa um Class Helper para adicionar ao componente TEdit a capacidade de validar seu texto, definindo se ele representa um CPF ou CNPJ.

01 unit UnitEditDocumento; 02 03 interface 04 05 uses 06 vcl.stdCtrls, SysUtils; 07 08 type 09 TEditDocumento = class helper for TEdit 10 private 11 function TextoSemSinais: string; 12 public 13 function isPessoaFisica: boolean; 14 function isPessoaJuridica: boolean; 15 end; 16 17 implementation 18 19 uses 20 UnitUtils; 21 22 { TEditDocumento } 23 24 function TEditDocumento.TextoSemSinais: string; 25 var 26 //Retorna o texto sem caracteres especiais 27 end; 28 29 function TEditDocumento.isPessoaFisica: boolean; 30 begin 31 result := length(TextoSemSinais) = 11; 32 end; 33 34 function TEditDocumento.isPessoaJuridica: boolean; 35 begin 36 result := length(TextoSemSinais) = 14; 37 end; 38 end
Listagem 1. Class Helper para um TEdit agregar métodos de validação

Linha 9: sintaxe para declaração do Class Helper. Essa instrução indica que está sendo criado um Class Helper (que é uma classe) para modificar o componente TEdit;

Linhas 10 a 15: declaração dos métodos da classe;

Linhas 24 a 37: implementação dos métodos da classe.

Perceba que toda a estrutura do Class Helper é a mesma de uma classe convencional, alterando apenas a forma de declaração.

Como utilizar

Sempre que for necessário utilizar um componente que possua o novo comportamento, basta adicionar o nome da unit em que está declarado o Class Helper na seção uses. A partir disso, será possível acessar os novos métodos adicionados, conforme mostra a Listagem 2.

01 procedure TForm5.Edit1Exit(Sender: TObject); 02 begin 03 if Edit1.isPessoaFisica then 04 Label1.Caption:='Documento Pessoa Física' 05 else 06 begin 07 if Edit1.isPessoaJuridica then 08 Label1.Caption:='Documento Pessoa Jurídica' 09 else 10 begin 11 Label2.Caption:='Documento Inválido'; 12 exit; 13 end; 14 end; 15 end;
Listagem 2. Utilizando os métodos adicionados pelo Class Helper

Nesse código, estamos trabalhando com o evento OnExit do componente TEdit, e nas linhas 3 e 7 utilizamos os novos métodos adicionados pelo Class Helper.

Modificando métodos existentes

Além de adicionar novos métodos, o Class Helper permite que modifiquemos os métodos já existentes em um componente. Na Listagem 3 apresentamos um exemplo de modificação do método Clear para uma situação especial em um formulário onde os componentes TEdit que aceitam texto recebem a string “xxxx” ao serem limpos, e os que aceitam apenas números recebem o texto “0000”. Esse comportamento pode ser necessário em algumas telas do sistema, a partir das quais temos, por exemplo, que imprimir o conteúdo em impressoras matriciais. Nesses casos, em planilhas de formulário contínuo, os campos não podem aparecer em branco para não descaracterizar a impressão.

01 Unit UnitEditMatricial; 02 ... 03 type 04 TEditDocumento = class helper for TEdit 05 public 06 procedure Clear; 07 end; 08 09 ... 10 11 procedure TEditDocumento.Clear; 12 begin 13 if NumbersOnly then 14 Text:= StringOfChar('0',MaxLength) 15 else 16 Text:=StringOfChar('X',MaxLength); 17 end;
Listagem 3. Class Helper para modificar um método já existente no TEdit

Agora, quando adicionarmos a referência a essa unit na seção uses e acionarmos o método Clear de um TEdit, esse novo método será executado, ao invés do procedimento padrão que elimina todo o texto do campo.

Motivação

Durante o desenvolvimento de aplicações Delphi é comum a necessidade de adicionar aos componentes visuais algumas funcionalidades extras, como validação e formatação de dados. Para atender a esse tipo de situação, alguns programadores optam por utilizar herança, enquanto outros alteram diretamente o código fonte do componente. Essas, porém, não são as melhores soluções, pois a herança obriga a utilização de uma nova classe, ao invés do componente padrão, e a alteração do código fonte pode gerar problemas em outras partes do sistema que utilizem esse mesmo componente.

A fim de suprir essa demanda, a partir da versão 2006 o Delphi passou a contar com um recurso chamado Class Helper, tornando possível adicionar novos comportamentos aos componentes sem usar herança ou modificar o código fonte original.

Saiba mais sobre a série de cursos sobre Delphi

Definição

No Delphi, Class Helper é um recurso que permite adicionar métodos e modificar comportamentos de componentes em tempo de execução, sem a necessidade de herdar a classe ou utilizar recursos de composição, fazendo parecer que a classe contém o novo comportamento desde sua criação.

Outro diferencial é que Class Helpers não se aplicam somente a componentes. Eles também permitem modificar classes de domínio criadas pelo desenvolvedor, adicionar métodos a estruturas do tipo record e tipos primitivos (introduzidos a partir da versão XE3). Nesse último caso, no entanto, não é possível adicionar propriedades.

Como criar

Na Listagem 1 é apresentada uma unit que implementa um Class Helper para adicionar ao componente TEdit a capacidade de validar seu texto, definindo se ele representa um CPF ou CNPJ.

01 unit UnitEditDocumento; 02 03 interface 04 05 uses 06 vcl.stdCtrls, SysUtils; 07 08 type 09 TEditDocumento = class helper for TEdit 10 private 11 function TextoSemSinais: string; 12 public 13 function isPessoaFisica: boolean; 14 function isPessoaJuridica: boolean; 15 end; 16 17 implementation 18 19 uses 20 UnitUtils; 21 22 { TEditDocumento } 23 24 function TEditDocumento.TextoSemSinais: string; 25 var 26 //Retorna o texto sem caracteres especiais 27 end; 28 29 function TEditDocumento.isPessoaFisica: boolean; 30 begin 31 result := length(TextoSemSinais) = 11; 32 end; 33 34 function TEditDocumento.isPessoaJuridica: boolean; 35 begin 36 result := length(TextoSemSinais) = 14; 37 end; 38 end
Listagem 1. Class Helper para um TEdit agregar métodos de validação

Linha 9: sintaxe para declaração do Class Helper. Essa instrução indica que está sendo criado um Class Helper (que é uma classe) para modificar o componente TEdit;

Linhas 10 a 15: declaração dos métodos da classe;

Linhas 24 a 37: implementação dos métodos da classe.

Perceba que toda a estrutura do Class Helper é a mesma de uma classe convencional, alterando apenas a forma de declaração.

Como utilizar

Sempre que for necessário utilizar um componente que possua o novo comportamento, basta adicionar o nome da unit em que está declarado o Class Helper na seção uses. A partir disso, será possível acessar os novos métodos adicionados, conforme mostra a Listagem 2.

01 procedure TForm5.Edit1Exit(Sender: TObject); 02 begin 03 if Edit1.isPessoaFisica then 04 Label1.Caption:='Documento Pessoa Física' 05 else 06 begin 07 if Edit1.isPessoaJuridica then 08 Label1.Caption:='Documento Pessoa Jurídica' 09 else 10 begin 11 Label2.Caption:='Documento Inválido'; 12 exit; 13 end; 14 end; 15 end;
Listagem 2. Utilizando os métodos adicionados pelo Class Helper

Nesse código, estamos trabalhando com o evento OnExit do componente TEdit, e nas linhas 3 e 7 utilizamos os novos métodos adicionados pelo Class Helper.

Modificando métodos existentes

Além de adicionar novos métodos, o Class Helper permite que modifiquemos os métodos já existentes em um componente. Na Listagem 3 apresentamos um exemplo de modificação do método Clear para uma situação especial em um formulário onde os componentes TEdit que aceitam texto recebem a string “xxxx” ao serem limpos, e os que aceitam apenas números recebem o texto “0000”. Esse comportamento pode ser necessário em algumas telas do sistema, a partir das quais temos, por exemplo, que imprimir o conteúdo em impressoras matriciais. Nesses casos, em planilhas de formulário contínuo, os campos não podem aparecer em branco para não descaracterizar a impressão.

01 Unit UnitEditMatricial; 02 ... 03 type 04 TEditDocumento = class helper for TEdit 05 public 06 procedure Clear; 07 end; 08 09 ... 10 11 procedure TEditDocumento.Clear; 12 begin 13 if NumbersOnly then 14 Text:= StringOfChar('0',MaxLength) 15 else 16 Text:=StringOfChar('X',MaxLength); 17 end;
Listagem 3. Class Helper para modificar um método já existente no TEdit

Agora, quando adicionarmos a referência a essa unit na seção uses e acionarmos o método Clear de um TEdit, esse novo método será executado, ao invés do procedimento padrão que elimina todo o texto do campo.

Artigos relacionados