使用Delphi在运行时注册一个新类

使用Delphi在运行时注册一个新类,delphi,Delphi,可以使用delphi在运行时创建(注册)一个新类 我有一个名为TMyForm的类,可以创建一个从TMyForm派生的新表单,但具有新的类类型 我想要这样的东西 var Myform : TMyForm; MyFormClassBase : TFormClass; begin MyFormClassBase := TFormClass(RegisterMyNewClass('TMyNewClass'));//obviously RegisterMyNewClass

可以使用delphi在运行时创建(注册)一个新类

我有一个名为TMyForm的类,可以创建一个从TMyForm派生的新表单,但具有新的类类型

我想要这样的东西

var
  Myform          : TMyForm;
  MyFormClassBase : TFormClass;
begin
  MyFormClassBase  := TFormClass(RegisterMyNewClass('TMyNewClass'));//obviously RegisterMyNewClass does not exist
  Myform := MyFormClassBase.Create(Application);
  Myform.Show;
end; 
FormCurrency:= TMyForm.Create( 'Define currencys', 'CURRENCYTABLE') 
if ValidateAccess(FormCurrency) then 
FormCurrency.Show
else
FormCurrency.Close;



FormGroups:= TMyForm.Create( 'Define Groups', 'GROUPSTABLE') 
if ValidateAccess(FormGroups) then 
FormGroups.Show
else 
FormGroups.Close;
我正在使用Delphi7

更新1

我不想创建同一基类的新实例,我需要在运行时创建一个从另一个类派生的新类类型

更新2

非常感谢您的关注。但是解释的目的有点复杂(因为我的英语不好)。我有一个表单,允许您编辑多个主数据表,所有这些表都有相同的字段代码(一个整数主键)和描述(一个varchar字段),它们用于定义货币、国家、项目、组等

因为所有这些表的逻辑都是相同的,所以只需要通过将表名的标题作为参数传递来管理这些表就可以了。像这样的

var
  Myform          : TMyForm;
  MyFormClassBase : TFormClass;
begin
  MyFormClassBase  := TFormClass(RegisterMyNewClass('TMyNewClass'));//obviously RegisterMyNewClass does not exist
  Myform := MyFormClassBase.Create(Application);
  Myform.Show;
end; 
FormCurrency:= TMyForm.Create( 'Define currencys', 'CURRENCYTABLE') 
if ValidateAccess(FormCurrency) then 
FormCurrency.Show
else
FormCurrency.Close;



FormGroups:= TMyForm.Create( 'Define Groups', 'GROUPSTABLE') 
if ValidateAccess(FormGroups) then 
FormGroups.Show
else 
FormGroups.Close;
另一方面,我有一个验证方法(称为ValidateAccess),它使用表单的类验证用户对表单的访问。因此,如果您使用相同类型的表单,那么对所有选项的访问都会受到限制,例如“定义组”、“定义货币”、“定义国家”(我不希望发生这种情况),因为我需要向ValidateAccess方法传递一个不同的类

我无法重写ValidateAccess方法,因为系统中已经注册了许多不同的表单

我不想一次又一次地创建一个新的表单类型和一个新的单元,只需要更改要使用的标题和表格


提前感谢。

为什么需要创建表单的新子类?您不能在运行时更改该新类的任何内容,使其与现有类不同。i、 e.不能添加新方法或属性

我怀疑您错误地认为一个表单类只能有一个实例。但事实并非如此。您可以创建任意数量的表单实例:

var
  formA : TMyForm;
  formB : TMyForm;
begin
  formA := TMyForm.Create(Application);
  formB := TMyForm.Create(Application);
  formA.Show;
  formB.Show;
end;

如果这不是您所需要的,那么您需要提供更多关于您正试图实现的目标的信息。

为什么需要创建表单的新子类?您不能在运行时更改该新类的任何内容,使其与现有类不同。i、 e.不能添加新方法或属性

我怀疑您错误地认为一个表单类只能有一个实例。但事实并非如此。您可以创建任意数量的表单实例:

var
  formA : TMyForm;
  formB : TMyForm;
begin
  formA := TMyForm.Create(Application);
  formB := TMyForm.Create(Application);
  formA.Show;
  formB.Show;
end;

如果这不是您所需要的,您将需要提供有关您正试图实现的具体目标的更多信息。

Delphi是一种“静态”语言,因此您无法在运行时创建新类型(或类)。您可以用一些“动态”语言来实现这一点,比如Python

如果您试图创建一个新表单,并填充不同的控件,您可以这样做,但您需要创建每个单独的控件,使表单成为父控件(和所有者),并设置其位置和标题等

procedure TForm1.Button1Click(ASender: TObject);
var
  LForm: TForm;
  LLabel: TLabel;
begin
  LForm := TForm.Create(nil);
  try

    LForm.Width := 100;
    LForm.Height := 100;

    LLabel := TLabel.Create(LForm);
    LLabel.Parent := LForm;
    LLabel.Caption := 'Hello World!';

    LForm.ShowModal;

  finally
    FreeAndNil(LForm);
  end;
end;

Delphi是一种“静态”语言,因此不能在运行时创建新类型(或类)。您可以用一些“动态”语言来实现这一点,比如Python

如果您试图创建一个新表单,并填充不同的控件,您可以这样做,但您需要创建每个单独的控件,使表单成为父控件(和所有者),并设置其位置和标题等

procedure TForm1.Button1Click(ASender: TObject);
var
  LForm: TForm;
  LLabel: TLabel;
begin
  LForm := TForm.Create(nil);
  try

    LForm.Width := 100;
    LForm.Height := 100;

    LLabel := TLabel.Create(LForm);
    LLabel.Parent := LForm;
    LLabel.Caption := 'Hello World!';

    LForm.ShowModal;

  finally
    FreeAndNil(LForm);
  end;
end;

IIUC,你可以有这样的东西:

TmyForm = class... //your normal form
...
public
  property Title: string read FTitle write SetTitle;
  property FormKind: TFormKind read FFormKind write SetFormKind;
  function ValidateAccess: boolean;
  ...
end;
其中
TFormKind=(fkCurrency,fkCountry,…)

SetTitle
中也将设置表单的标题,在
SetFormKind
中,如果需要,您将执行coresponding初始化,而在
ValidateAccess
中,您将根据
FFormKind
的值处理不同的情况(很可能是在
情况下)

使用它:

myForm:=TmyForm.Create(Application); //since we'll free it the owner can be also 'nil'
myForm.Title:='Boo!';
myForm.Kind:=fkCurrency;
if myForm.ValidateAccess then
  myForm.ShowModal; //btw your 'if' structure is a little bit 'odd' to say at least. You don't need to call Close on a form which isn't showing

myForm.Free; //get rid of it. - of course this applies if we created it. Not applicable if you use 'Show' only, of course.

但是,您可能会发现,根据表单的属性等,最好将层分开,并使用不同的类来处理验证。

IIUC,您可以使用以下内容:

TmyForm = class... //your normal form
...
public
  property Title: string read FTitle write SetTitle;
  property FormKind: TFormKind read FFormKind write SetFormKind;
  function ValidateAccess: boolean;
  ...
end;
其中
TFormKind=(fkCurrency,fkCountry,…)

SetTitle
中也将设置表单的标题,在
SetFormKind
中,如果需要,您将执行coresponding初始化,而在
ValidateAccess
中,您将根据
FFormKind
的值处理不同的情况(很可能是在
情况下)

使用它:

myForm:=TmyForm.Create(Application); //since we'll free it the owner can be also 'nil'
myForm.Title:='Boo!';
myForm.Kind:=fkCurrency;
if myForm.ValidateAccess then
  myForm.ShowModal; //btw your 'if' structure is a little bit 'odd' to say at least. You don't need to call Close on a form which isn't showing

myForm.Free; //get rid of it. - of course this applies if we created it. Not applicable if you use 'Show' only, of course.

但是,您可能会发现,根据表单的属性等,最好将各层分开,并使用不同的类来处理验证。

我不知道您是否理解正确,但我的理解可以通过以下方式实现:

type
  TCurrencyForm = class(TMyForm);
  TGroupsForm = class(TMyForm);


FormCurrency:= TCurrencyForm.Create( 'Define currencys', 'CURRENCYTABLE') 
if ValidateAccess(FormCurrency) then 
FormCurrency.Show
else
FormCurrency.Close;

FormGroups:= TGroupsForm.Create( 'Define Groups', 'GROUPSTABLE') 
if ValidateAccess(FormGroups) then 
FormGroups.Show
else 
FormGroups.Close;
在ValidateAccess方法中(假设参数名为Form),可以检查以下内容:

if Form is TCurrencyForm then
else if Form is TGroupsForm then 

如果您没有访问新表单类声明的权限,可以改用form.ClassName。

我不知道您的理解是否正确,但我的理解可以通过以下方式实现:

type
  TCurrencyForm = class(TMyForm);
  TGroupsForm = class(TMyForm);


FormCurrency:= TCurrencyForm.Create( 'Define currencys', 'CURRENCYTABLE') 
if ValidateAccess(FormCurrency) then 
FormCurrency.Show
else
FormCurrency.Close;

FormGroups:= TGroupsForm.Create( 'Define Groups', 'GROUPSTABLE') 
if ValidateAccess(FormGroups) then 
FormGroups.Show
else 
FormGroups.Close;
在ValidateAccess方法中(假设参数名为Form),可以检查以下内容:

if Form is TCurrencyForm then
else if Form is TGroupsForm then 

如果您没有访问新表单类声明的权限,可以改用form.ClassName。

看起来我们已经设法解决了您的问题。我应该声明可以在运行时添加新的类类型。类由它们的类引用定义,类引用是指向VMT(虚拟方法表)的指针,如果您知道VMT的布局,您可以创建自己的类引用。不幸的是,音频质量太差了(

当然,这对您没有多大用处,除非您必须创建在编译时定义不可用的类,例如,如果您使用的是脚本引擎