Delphi 动态加载任意窗体并显示 ( 积分: 200 )

  • 主题发起人 主题发起人 hanmon
  • 开始时间 开始时间
H

hanmon

Unregistered / Unconfirmed
GUEST, unregistred user!
假定有若干个窗体Form1,Form2...Formn,如何根据他们的名称输入来加载并显示它?

如给定'Form4',则加载并显示它

前提是它们都没有被创建:程序大了,不用的窗体初始化都被创建但没有被显示是很累的.

前提:
1.被调窗体没有被Create
2.其类型只能通过字符串访问而不得通过已知类来访问
如: With f('Form2').Create(..) Do Begin
ShowModal;
Free;
End;
关键是这个f函数如何实现,如我在文本框里输入窗体名称,它就显示对应的窗体,别告诉我用静态的穷举的方法(200分哪,当然不是很容易挣的哦!)
if .. then
application.createform(tform2,form2)
else if .. then
application.createform(tform3,form3)
...
 
在这些窗体的initialization 中写下这样的代码:
RegisterClass(窗体类);

然后在主窗体中调用:
var
AClass:TClass;
AForm:TForm;
begin
AClass:=GetClass(窗体类);
Application.CreateForm(TComponentClass(AClass), AForm);
AForm.Show;
end;
 
procedure TForm1.CreatWins(NewForm: TForm; FormClass: TFormClass);
begin
{ 创建窗体 }
if not Assigned(NewForm) then
NewForm := FormClass.Create(Application);
NewForm.ShowModal;
end;

procedure TForm1.aa;
begin
{ 创建窗体FrmMessage }
CreatWins(FrmMessage, TFrmMessage);
end;
 
补充一点:
1.被调窗口必须是没有创建的.
2.用字符串指定(动态的意义在于此),而不是强制指定,如lizhenhe老兄的TFrmMessage就不符合要求.

我要将除主窗体之外的所有子窗体的信息录入到数据库中,从动态菜单中读出任何被调的子窗体名称的字符串来创建窗体实例并显示ShowModal或Show之
 
xingkong97老兄的方法有点意思
我在Form2,3中分别加入了:
initialization
RegisterClass(TForm2);
initialization
RegisterClass(TForm3);
但测试报了".... . Read of address ..."的错误.请继续指教.

lizhenhe老兄的例子依然建立在静态已知对象的类型TFrmMessage的基础上的.不是我的要求,不过依然感谢!!!
 
有点奇怪.当然是知道 Form2 是 TForm2类的对象才行的啊,而且没创建的对象什么都没有,难道你以为在ide中写了个 Form2 :TForm2 ; 然后就可以按名字来创建了?连个关联都没有?最起码就首先要知道 Form2 与 TForm2的关联性,不然这算哪门的问题, Form2没创建,那么用类 TForm2 随便创建一个就可以了
 
type
TFormClasss = class of TForm ;

const
ClassList : array[0..1] of TFormClasss = (TForm2,TForm3) ;

procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer ;
frm : TForm ;
begin
for i := 0 to 1 do begin
if ClassList.ClassName = Edit1.Text then begin
frm := TForm ( ClassList.NewInstance ).Create(nil ) ;
frm.Name := Edit1.Text ;
with frm do begin
try
ShowModal ;
finally
Free ;
end;
end;
end;
end;
end;
 
以上过程可以根据类的名创建一个可命名的对象~~,未create的对象如果你系统中没有保存它的信息的话,是不可以用名字就知道它是属于哪个类.
 
xingkong97, 答案是正确的。我用了很久。
ztf86781163, 的答案看起来很猛,不知道能不能用。
 
同意 xingkong97, 其实在离线资料中搜一下 RegisterClass, FindClass 就可以找到答案了
 
没有错啊,
下面是我的测试代码:
在主窗体中:
procedure TForm1.btn2Click(Sender: TObject);
var
AClass:TClass;
AForm:TForm;
begin
AClass:=GetClass(edt3.Text);//edt3.Text是窗体在initialization中的
//注册窗体类(TForm2,TForm3...)
if AClass=nil then Exit;
Application.CreateForm(TComponentClass(AClass), AForm);
AForm.Show;
end

-----------------------------------------
在unit2中:
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

initialization
RegisterClass(TForm2);
end.
 
rogue:测试一下不就知道了吗?
 
多人接受答案了。
 
后退
顶部