Colunista ainda sem descrição. Caro colunista, por favor envie-nos sua descrição.
Classes Persistentes
Classes persistentes são aquelas compiladas com a diretiva de compilador {$M+} ativada, ou descendentes delas. Essa diretiva faz o compilador gerar informação de RTTI (runtime type information, ou informação sobre o tipo em tempo de execução), permitindo assim, como o nome diz, a persistência das informações contidas em classes persistentes. Um exemplo disso em ação é a criação de um formulário e seus componentes através de um DFM. Todos os componentes que são salvos em DFMs, são, necessariamente, descendentes de TPersistent.
RegisterClass/GetClass
Existe um mecanismo de registro de Classes, no Delphi. É uma lista que guarda todas as classes registradas. RegisterClass adiciona uma classe persistente nesta lista. GetClass retorna, pelo nome, uma dessas classes. Simples assim. Podemos ver a implementação desse mecanismo em classes.pas.
Um exemplo
Vamos fazer, então o exemplo citado anteriormente: criar formulários dinamicamente, pelo nome. Cada formulário precisa ser registrado. O momento mais apropriado para isso é na inicialização da unit relacionada ao componente. Ficaria algo assim:
implementation
{$R *.dfm}
// Todo o código da unit aqui
initialization
RegisterClass(TForm2); // Espero que seu form não chame Form2
end.
Para criar esse formulário, poderia ser usada uma função semelhante a seguinte:
function CriaForm(const NomeForm: string): TForm;
var
TClasse : TPersistentClass;
begin
Result := nil;
TClasse := GetClass(NomeForm);
if (TClasse <> nil) and TClasse.InheritsFrom(TForm) then
Result := TFormClass(TClasse).Create(nil);
end;
O cast, no final, de TPersistentClass para TFormClass, é para poder chamar o constructor introduzido em TComponent, que aceita o Owner como parâmetro. Essa função seria chamada de uma forma semelhante à seguinte:
var
Form : TForm;
begin
Form := CriaForm('Form2');
if not Assigned(Form) then
MessageDlg('Form não registrado!', mtError, [mbOK], 0)
else
begin
Form.ShowModal;
Form.Free;
end;
end;
Não se esqueça que será retornada uma instância de TForm2, mas contida em uma variável do tipo TForm. Para chamar os métodos específicos contidos no form descendente, só sabendo a classe em tempo de projeto (e fazendo um cast), ou por RTTI.
Listando as classes Registradas
Além de RegisterClass e GetClass, existem diversos métodos de manipulação desse registro de classes em classes.pas. Um deles está demonstrado na unit seguinte:
unit ClassesEnum;
interface
uses
Classes;
procedure EnumClasses(Strings: TStrings);
implementation
type
TClassesEnum = class(TObject)
private
FStrings : TStrings;
procedure GetClassesProc(AClass: TPersistentClass);
public
procedure EnumClasses(Strings: TStrings);
end;
procedure EnumClasses(Strings: TStrings);
begin
with TClassesEnum.Create do
try
EnumClasses(Strings);
finally
Free;
end;
end;
{ TClassesEnum }
procedure TClassesEnum.EnumClasses(Strings: TStrings);
begin
if not Assigned(Strings) then
Exit;
FStrings := Strings;
with TClassFinder.Create(nil, True) do
try
GetClasses(GetClassesProc);
finally
Free;
end;
end;
procedure TClassesEnum.GetClassesProc(AClass: TPersistentClass);
begin
FStrings.Add(AClass.ClassName);
end;
end.
Esse exemplo se vale do método GetClasses, de TClassFinder, para listar as classes registradas. Para ver isso em ação, adicione o seguinte código no FormCreate de um formulário contendo um ListBox:
procedure TForm1.FormCreate(Sender: TObject);
begin
EnumClasses(ListBox1.Items);
end;
A partir daí, basta usar GetClass para obter referências as classes listadas, como feito anteriormente.
Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009