使用Delphi在运行时注册一个新类
可以使用delphi在运行时创建(注册)一个新类 我有一个名为TMyForm的类,可以创建一个从TMyForm派生的新表单,但具有新的类类型 我想要这样的东西使用Delphi在运行时注册一个新类,delphi,Delphi,可以使用delphi在运行时创建(注册)一个新类 我有一个名为TMyForm的类,可以创建一个从TMyForm派生的新表单,但具有新的类类型 我想要这样的东西 var Myform : TMyForm; MyFormClassBase : TFormClass; begin MyFormClassBase := TFormClass(RegisterMyNewClass('TMyNewClass'));//obviously RegisterMyNewClass
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的布局,您可以创建自己的类引用。不幸的是,音频质量太差了(
当然,这对您没有多大用处,除非您必须创建在编译时定义不可用的类,例如,如果您使用的是脚本引擎