Desenvolvimento - Delphi
Classe Genérica para Transformar Tipos ENUM Para TStrings em Delphi
Veja neste artigo como criar uma classe genérica que transforma tipos ENUM enumerados em TStrings usando o Delphi.
por Marco Antonio SallesQuem é que nunca utilizou tipos enumerados para dar um suporte mais orientado à aplicação? Quem é que nunca precisou carregar um Tstrings com as opções do Tipo Enum? Quem é que nunca fez certas artimanhas para passar de String para ENUM e Vice-versa? Pois bem, o artigo de hoje não é somente mais uma das inúmeras opções que se encontram espalhadas na rede sobre o assunto, o propósito é criar um classe que seja desaclopada com um tipo Enum específico .
Com isto teremos mais flexibilidade e reaproveitamento do código em toda a VCL , onde tentamos andar sempre perto da POO , pois todo esforço a mais agora , será recompensado num futuro próximo .
Vamos ao código ???
Em uma Unit escreva a classe a seguir:
Listagem 1: Escrevendo Classes na Unit
unit uEnunConvertString; interface uses classes,Generics.Collections; Type TGenerico = 0..255; TConvert<T:record> = class private public class procedure PopulateListEnum(AList: TStrings); class function StrConvertEnum(const AStr: string):T; class function EnumConvertStr(const eEnum:T):string; end; implementation uses Variants,SysUtils,TypInfo; { TConvert } class procedure TConvert<T>.PopulateListEnum(AList: TStrings); var i:integer; StrTexto:String; Enum:Integer; begin i:=0; try repeat StrTexto:=trim(GetEnumName(TypeInfo(T), i)); Enum:=GetEnumValue(TypeInfo(T),StrTexto); AList.Add(StrTexto); inc(i); until Enum < 0 ; AList.Delete(pred(AList.Count)); except; raise EConvertError.Create( 'O Parâmetro passado não corresponde a um Tipo ENUM'); end; end; {*******************************************************************************} class function TConvert<T>.StrConvertEnum(const AStr: string):T; var P:^T; num:Integer; begin try num:=GetEnumValue(TypeInfo(T),Astr); if num = -1 then abort; P:=@num; result:=P^; except raise EConvertError.Create(' O Parâmetro "'+Astr+'" passado não '+sLineBreak+ ' corresponde a um Tipo Enumerado'); end; end; {******************************************************************************} class function TConvert<T>.EnumConvertStr(const eEnum:T): String; var P:PInteger; Num:integer; begin try P:=@eEnum; Num:=integer(TGenerico((P^))); Result := GetEnumName(TypeInfo(T),Num); except raise EConvertError.Create( 'O Parâmetro passado não corresponde a '+sLineBreak+ 'um inteiro Ou a um Tipo Enumerado'); end; end; end.
Algumas observações:
- Esta unidade contém uma classe TConvert utilizando o conceito de Generics introduzido no Delphi2009.
- Também aplicamos o conceito de Constraints utilizado neste caso para parametrizar o tipo genérico. Ao fizermos <T:record> definimos que o tipo real a ser utilizado deverá ser uma estrtutura de valor e não de referência, podendo ser um valor ordinário, ponto flutuante, ou um Record.
- Limitamos com isto, que se use de forma errada a classe, restringindo mau uso e mau funcionamento da mesma. Por exemplo : TConvert.PopulateListEnum<TObject>() ; não chega nem a compilar.
Vamos agora fritar os bolinhos, afinal, uma classe deve fornecer os bolinhos para serem consumidos :
Em um formulário qualquer, vamos definir vários tipos a seguir enumerados:
- Type TAcao= (ftFirist, ftNext, ftPrior, FtLast, ftIgnore ) ;
- Type TRemuneracao = (ftHorario, ftDiario, FtSemanal , ftquinzenal , Ftmensal);
- Type TVencimentos = (ftMedia30, FtMedia45 , ftMedia60);
- Type TDinheiro = (ftReal , ftDollar , FtEuros, ftLibra , ftYen , ftPeso );
- Type TSorte = (ftPar , FtImpar);
- type TPort = (COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9);
Nosso primeiro objetivo é popular 6(seis) combobox respectivamente (cbAcao, cbRemuneracao, cbVencimentos, cbDinheiro, cbSorte, cbPort), utilizando a classe que se encontra na unidade UEnunConvertString. Para Isto De Uses a esta Unidade no Formulário que se encontra os 6(seis) Combobox e programe no evento onClick do Botão o seguinte Código:
Listagem 2: Programando evento onClick
procedure TForm1.btnPopularClick(Sender: TObject); begin TConvert<TAcao>.PopulateListEnum(CbAcao.Items); TConvert<TRemuneracao>.PopulateListEnum(cbRemuneracao.Items); TConvert<TVencimentos>.PopulateListEnum(cbVencimentos.Items); TConvert<TDinheiro>.PopulateListEnum(cbDinheiro.Items); TConvert<TSorte>.PopulateListEnum(cbSorte.Items); TConvert<TPort>.PopulateListEnum(cbPort.Items); end;
O Resultado são os 6(seis) Combobox “populados” sem alterarmos uma linha sequer do código. Esta Classe é expansível, flexível e suporta, a princípio, todos os tipos enumerados. Os outros métodos não vão ser detalhados, visto a sua simplicidade e alto didática. Se por ventura alguém tiver alguma dúvida na utilização desses métodos pode entrar em contado que será atendido.
Peço por último, por questões de gentileza e cordialidade, bem como respeito aos direitos autorais, que se alguém quiser acrescentar esta classe em algum veiculo de comunicação, que faça referência a fonte da informação original. No mais meu muito obrigado.
Blog do Autor: http://marcosalles.wordpress.com/