关于在一个自定义过程中动态建立窗口的问题,大家瞧一下?!(100分)

  • 主题发起人 主题发起人 apex
  • 开始时间 开始时间
A

apex

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个自定义过程中动态建立窗口,在unit1中过程如下:
procedure TForm1.ShowFrm(FrmName:TForm; ClsName:string);
var F : Tformclass;
begin
if not assigned(Frmname) then
begin
F := TFormClass(findClass(clsname));
FrmName := F.Create(application);
FrmName.Show;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
showfrm(form2,'tform2');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterClass(Tform2);
RegisterClass(Tform3);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
showfrm(form3,'tform3');
end;

在unit2中有以下代码用于释放窗口:
procedure TForm2.Button1Click(Sender: TObject);
begin
release;
form2 := nil;
end;
unit3中也有同样代码。

可是assigned函数的返回值每次都是nil,也就是说不能控制一个窗口的重复显示,用
findwindow函数也解决不了问题,各位请给我找找原因。(关于frmshow过程可参见
问题“105450”)
 
??没人回答??
 
procedure TForm1.ShowFrm(FrmName:TForm; ClsName:string);
应该是
procedure TForm1.ShowFrm(var FrmName:TForm; ClsName:string);
否则,在函数内部赋的值,到外边就没有了。

 
to dreamtiger:
你的回答没错,但这样我在调用showfrm(form3,'tform3');时,编译报告说form3这部
份形参和实参类型不符,用以下方法showfrm(tform(form3),'tform3');就可以了,这
是什么原因,可以给我一个理由吗?
 
你首先要理解IS 和 AS的语法其实你使用TFORM()也就是类的强行转换而已,更好的方法是用
IS和AS 来转换判断。
 
Pascal是强类型语言,TForm3和TForm当然是不匹配的类型。
你可以参考一下Application.CreateForm的源码。
 
ShowFrm这样写

procedure TForm1.ShowFrm(var FrmName; ClsName: String);
var
F: TFormClass;
begin
if Pointer(FrmName) = nil then begin
F := TFormClass(FindClass(ClsName));
TForm(FrmName) := F.Create(Application);
TForm(FrmName).Show;
end;
end;

 
用 SysUtils unit 的 FreeAndNil 方法释放窗口,然后直接判断 Form1 = nil ,没必要使用 Assigned
procedure FreeAndNil(var Obj);
var
P: TObject;
begin
P := TObject(Obj);
TObject(Obj) := nil; // clear the reference before destroying the object
P.Free;
end;
 
多人接受答案了。
 
后退
顶部