Como registrar uma classe tendo somente o nome na string?
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:
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.
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
Curtidas 0
Respostas
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.
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
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:
e testei assim tb:
Sendo que das duas maneiras q eu tentei, as duas falharam!! :?
Isto tá muito dificil pra mim! :cry:
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
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
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
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