您在 cmets 中添加了您将 FForm 设置为等于有效的现有表单。如果是这样,您可能不需要创建任何东西:
procedure TMyComp.Execute_FormShowModal;
var
frm: TFormUser;
begin
frm:= TFormUser(FForm);
frm.BtnOK.Enabled:=False;
frm.ShowModal;
//frm.Free;
end;
这假定您所引用的这个有效实例已声明
type
TFormUser = class(TForm)
BtnOK : TButton;
// etc...
end;
如果您尝试制作表单的副本,您可以使用:
procedure TMyComp.Execute_FormShowModal;
var
frm: TFormUser;
begin
frm:= TFormUser(TFormClass(FForm.ClassType).Create(FParentForm));
// which is no different than:
frm:= TFormUser.Create(FParentForm));
frm.BtnOK.Enabled:=False;
frm.ShowModal;
frm.Free;
end;
如果要操作表单上的控件(即 BtnOK),那么您需要知道表单的类类型(本例中为 TFormUser)。因此,既需要知道表单的确切类类型,又想从设计时建立的类型中实例化表单,这是矛盾的。
由于您可能试图在不“知道”其绝对类型的情况下实例化表单,因此您的 FForm 属性应该是表单的 类。
假设您没有在组件中发布“Form”属性,我将对您的组件进行以下更改:
TMyComp = class(TComponent)
FFormClass : TFormClass;
procedure SetFormClass(Value : TFormClass);
property FormClass: TFormClass read FFormClass write SetFormClass;
procedure Execute_FormShowModal;
end;
您提到的初始化代码可能如下所示:
begin
// .....
//MyComp.Form := FormUser1;
MyComp.FormClass := TFormUser;
// .....
end;
然后“Execute_FormShowModal”就变成了:
procedure TMyComp.Execute_FormShowModal;
var
frm: TForm;
begin
// Check that FFormClass is not nil and perform some alternate
// action.
// if FFormClass = nil then ......
//
frm:= FFormClass.Create(FParentForm);
frm.ShowModal;
frm.Free;
end;
当然,您可能还想添加一些代码来检查 FFormClass 是否为 nil,如果是,则执行一些替代行为,例如引发异常或显示一些消息,甚至实例化默认表单。
如果您要发布 Form 属性,那么它将无法处理您的 FForm 字段值为 nil 的情况,因为您不知道或没有特定的类类型来实例化 Form。那就是:
frm:= TFormClass(FForm.ClassType).Create(FParentForm);
只会显示一个空白的空表单。
如果你想发布这个属性,你可以尝试把它变成一个字符串类型,它带有你想要实例化的表单类的name,然后使用 RTTI 来查找类:
uses RTTI;
TMyComp = class(TComponent)
FFormClassName : string;
procedure SetFormClassName(const Value : string);
property FormClassName: string read FFormClassName write SetFormClassName;
procedure Execute_FormShowModal;
end;
procedure TMyComp.Execute_FormShowModal;
var
frmCls : TFormClass;
frm: TForm;
RTTI : TRTTIContext;
RTTIType : TRTTIType;
begin
frmCls := nil;
for RTTIType in RTTI.GetTypes do
begin
if (RTTIType.Name = FFormClassName) and (RTTIType.TypeKind = tkClass) then
begin
if RTTIType.Handle.TypeData.ClassType.InheritsFrom(TForm) then
begin
frmClass := TFormClass(RTTIType.Handle.TypeData.ClassType);
break;
end;
end;
end;
// Check that frmCls is not nil and perform some alternate
// action.
// if frmCls = nil then ......
//
frm:= frmCls.Create(FParentForm);
frm.ShowModal;
frm.Free;
end;