有朋友和我讨论过,已经知道一个类名,怎么才能创建一个实列。一个偶然的机会发现很好做。
用Tform来做个试验吧。
1、新建工程,主form为form1,保存为unit1,添加一个form2,保存为unit2。
2、 在unit2中TForm2 = class(TForm)前面加上
TmyForm = class of Tform2;//相当于给Tform2加上一个别名
3、 在form1的FormCreate中写入RegisterClasses([TForm2]);//注册Tform2类
4、 在form1的button的单击事件中加入
var
A : Tform ;
begin
if GetClass('TForm2') =nil then exit ;
a := TMyform(GetClass('TForm2')).Create(nil);
a.show;
end;
搞定!
当然很多情况下,大家不会这样做。不过也可以试验一下。
比如,我有很多地方都需要调用各种的参数配置对话框,然而,我想偷懒,不想写太多的代码。我就可以通过发自定义消息的办法。先将所有的对话框类名写入一个数组中去。在需要调用的参数配置对话框的时候,发一个消息。接收消息的模块,就通过他发送过来的值,比如是一个int类型的id,我可以根据这个id在数组中找到类名,然后用上面的方法就可以搞定了。当然就节约了很多的代码了。
-----------------
欢迎讨论
用Tform来做个试验吧。
1、新建工程,主form为form1,保存为unit1,添加一个form2,保存为unit2。
2、 在unit2中TForm2 = class(TForm)前面加上
TmyForm = class of Tform2;//相当于给Tform2加上一个别名
3、 在form1的FormCreate中写入RegisterClasses([TForm2]);//注册Tform2类
4、 在form1的button的单击事件中加入
var
A : Tform ;
begin
if GetClass('TForm2') =nil then exit ;
a := TMyform(GetClass('TForm2')).Create(nil);
a.show;
end;
搞定!
当然很多情况下,大家不会这样做。不过也可以试验一下。
比如,我有很多地方都需要调用各种的参数配置对话框,然而,我想偷懒,不想写太多的代码。我就可以通过发自定义消息的办法。先将所有的对话框类名写入一个数组中去。在需要调用的参数配置对话框的时候,发一个消息。接收消息的模块,就通过他发送过来的值,比如是一个int类型的id,我可以根据这个id在数组中找到类名,然后用上面的方法就可以搞定了。当然就节约了很多的代码了。
-----------------
欢迎讨论
var
A : Tform ;
begin
if GetClass('TForm2') =nil then exit ;
a := TMyform(GetClass('TForm2')).Create(nil);
a.show;
end;
上面的这段代码对另外的Form,如form3也能用吗?
也可以改成Tform2的父类
TmyForm = class of Tform,效果是一样的
的确还没有试过,不过VC MFC RTTI里面有GetObject可以达到这种要求,delphi的RTTI应该不比VC弱才对阿
不过
3、 在form1的FormCreate中写入RegisterClasses([TForm2]);//注册Tform2类
对TForm2类有什么要求,只要uses包含这个类的unit就可以了吗
WParam: string): Integer;
type
THWLPClass = class of THWLogicProcessor;
var
aHWLPClass: THWLPClass;
bHWLPClass: THWLogicProcessor;
begin
aHWLPClass := THWLPClass(FindClass(LPName));
bHWLPClass := aHWLPClass.Create;
try
bHWLPClass.Provider := Self;
bHWLPClass.DBAccess := ServerDBAccess;
Result := bHWLPClass.Execute(MethodName, LParam, WParam);
finally
bHWLPClass.Free;
end;
end;中间层封装业务逻辑的例子,LPName是业务逻辑的功能unit,MethodName是unit中的函数, LParam, WParam是参数.和楼主差不多的例子,不过registerclasses我还是觉的写在类单元里比较好
具体的技术我不太清楚,听大家讨论~~
...
Property vForm : TForm Read FNext Write FNext;...
var
Form1 : TForm1;
implementation
Uses
Unit2;
...
....
Procedure TForm1 -> Button OnClick(Sender : TObject);
begin
if Assigned(FForm) then
TForm2(FForm).Show;
end;
Program Project1
uses
.....begin
Application.Initialize;
.........
Form1.vForm := Form2;
Application.Run;
end.
----------------
沉沦中..........
RegisterClasses([TForm_ManWellInfo_Mode,TForm_Pole_Mode,TForm_Pipe_Mode,
TForm_ExBox_Mode,TForm_SubBox_Mode,TForm_LCable_Mode]);
……
procedure TBasic_Form.Bbtn_OpenModeClick(Sender: TObject);
var
sModeName:string;
FormClass: TFormClass;
FormObject: TObject;
begin
sModeName:=Self.Name+'_Mode';
FormClass := TFormClass(GetClass(sModeName));
FormObject := FormClass.Create(nil);
TForm_Basic_Mode(FormObject).ShowModal;
end;
这个在delphi里面就是TFormClass = class of TForm; 在 Forms单元里面有的定义。RegisterClasses的方便就是它能在已知类的名称(字符串)的情况下用GetClass方法,得到类。但是通常这个可以回避。
下面是我在MDI程序里避免一个窗口被多次创建的代码用到了 TFormClass.function TFrmMain.ShowMDIChildWindowEx(ClsFrm: TFormClass;
bRestore: boolean): boolean;
var
i: integer;
frm: TForm;
begin
result:= false;
frm:= nil;
for i:=0 to self.MDIChildCount-1 do
if (Self.MDIChildren[i].ClassNameIs(ClsFrm.ClassName)) then begin
frm:= Self.MDIChildren[i];
break;
end;
try
if (frm = nil) then begin
frm:= ClsFrm.Create(self);
if self.MDIChildCount <= 1 then
frm.WindowState:= wsMaximized;
end; // end of if
with frm do begin
if (bRestore) then begin
if (WindowState = wsMinimized) then
WindowState:= wsNormal;
end;
Show;
end;
Result:= true;
except
on E: Exception do
MessageBox(0, pchar('错误。'#10#13'' + E.Message),'', MB_ICONERROR);
end;
end;
使用方法
procedure TFrmMain.actSLogManagerExecute(Sender: TObject);
begin
ShowMDIChildWindowEx(TFrmLogManager, true);
end;
a:TForm2;
end;
a:=TForm2.create(nil);
a.show;