Como registrar uma classe tendo somente o nome na string?

Delphi

16/01/2007

Pois então galera, a minha duvida tá toda no assunto do tópico!!

Preciso registrar uma classe, sendo que esta está contida dentro de uma package (.bpl).
Por padrão, toda package tem o nome da classe sem o ´T´ inicial.
A partir deste padrão fiz as seguintes funções para facilitar:

{$Region´Variaveis´}
var
  DinamicClass: Array of TPersistentClass;
  Packages: Array of Cardinal;
{$EndRegion}

{$R *.dfm}

{$Region´Funcoes para componentes extras´}
function GetClassNameFromBpl(FileName: String): String;
begin
  if FileExists(FileName) then
    begin
      Result := ExtractFileName(FileName);
      Result := Copy(Result,1,Length(Result)-4);
      Result := ´T´ + Result;
    end;
end;

function GetClassFromBpl(FileName: String): TPersistentClass;
begin
  Result := GetClass(GetClassNameFromBpl(FileName));
end;

procedure CarregaBpl(FileName: String);
begin
  //-- Carrega a BPL
  SetLength(Packages,Length(Packages)+1);
  Packages[Length(Packages)-1] := LoadPackage(FileName);
  //-- Pega nome da classe
  SetLength(DinamicClass,Length(DinamicClass)+1);
  RegisterClass(GetClass(GetClassNameFromBpl(FileName)));
  DinamicClass[Length(DinamicClass)-1] := GetClass(GetClassNameFromBpl(FileName));
end;

procedure DescarregaBpl;
var
  i: Integer;
begin
  //-- Descarrega as packages
  for i := 0 to Length(Packages) - 1 do
    UnloadPackage(Packages[i]);
  //-- Desregistra as classes
  UnRegisterClasses(DinamicClass);
end;
{$EndRegion}


O ponto crítico é na linha [color=green:cac9145575] RegisterClass(GetClass(GetClassNameFromBpl(FileName)));[/color:cac9145575], onde eu tento pegar a classe (TPersistentClass), através da função [color=green:cac9145575]GetClass() [/color:cac9145575] para registra-la, mas isto não está dando certo, pois, pelo que entendi na documentação do delphi, o [color=green:cac9145575]GetClass()[/color:cac9145575] e [color=green:cac9145575]FindClass()[/color:cac9145575] só funcionam com funções previamente registradas!!!

Eu já sei o que estou fazendo errado, mas não sei corrigir, alguem pode me ajudar???
Serei muito grato.


Aloizio Castro

Aloizio Castro

Curtidas 0

Respostas

Massuda

Massuda

16/01/2007

Se você observar os packages de componentes, verá que o RegisterClass é feito na inicialização das units que estão no package, não no programa que carrega os packages (senão a IDE teria que saber os nomes de todos os componentes que ela tem que carregar do package).

Para isso funcionar, o programa que vai carregar os packages precisa usar packages também (ao menos, acho, o da VCL) para ser possível ter uma lista única de classes do programa. Se você não usar o package da VCL, você vai acabar com uma lista de classes do programa (na cópia da VCL usada pelo programa) e outra lista de classes do package (na cópia da VCL usada pelo package) e o RegisterClass dentro do package não vai afetar a lista de classes do programa.


GOSTEI 0
Aloizio Castro

Aloizio Castro

16/01/2007

Massuda, realmente sua dica tem lógica, sendo que eu varri algumas units no diretorio do delphi e não achei exemplos, daew eu teste das seguintes maneiras:

unit ClassName;

interface

uses
  Controls, Classes, Dialogs;

type
  TClassName = class(TCustomControl)
  private
  public
    property Canvas;
    property OnMouseMove;
  published
  end;

procedure register;

implementation

{$R ClassName.res}

procedure register;
begin
  RegisterClass(TClassName);
  ShowMessage(´TClassName registrado´)
end;

end.


e testei assim tb:

unit ClassName;

interface

uses
  Controls, Classes, Dialogs;

type
  TClassName = class(TCustomControl)
  private
  public
    property Canvas;
    property OnMouseMove;
  published
  end;

procedure register;

implementation

{$R ClassName.res}

initialization
  RegisterClass(TClassName);

finalization
  UnRegisterClass(TClassName);

end.


Sendo que das duas maneiras q eu tentei, as duas falharam!! :?

Isto tá muito dificil pra mim! :cry:


GOSTEI 0
Massuda

Massuda

16/01/2007

Pondo a unit ClassName num package e fazendo um programa que carrega o package com LoadLibrary, FindClass funciona sem problemas e encontra TClassName; tirando o RegisterClass da inicialização da unit, FindClass falha. Não esqueça de compilar o programa que carrega o package com a opção para usar runtime packages.


GOSTEI 0
Massuda

Massuda

16/01/2007

Esqueci de mencionar.. usei algo parecido com o seu exemplo usando a parte de inicialização/finalização da unit.


GOSTEI 0
Aloizio Castro

Aloizio Castro

16/01/2007

Pondo a unit ClassName num package e fazendo um programa que carrega o package com LoadLibrary, FindClass funciona sem problemas e encontra TClassName; tirando o RegisterClass da inicialização da unit, FindClass falha. Não esqueça de compilar o programa que carrega o package com a opção para usar runtime packages.


Massuda, bem lembrado, meu erro estava em não [b:f001bd6ac7]registrar a classe na Unit da propria classe[/b:f001bd6ac7] e em não marcar a opção [b:f001bd6ac7]Build with runtime packages[/b:f001bd6ac7].

Muito obrigado, meu projeto voltou a caminhar!!!


GOSTEI 0
POSTAR