关于动态FROM问题...请关注(50分)

  • 主题发起人 主题发起人 zml
  • 开始时间 开始时间
Z

zml

Unregistered / Unconfirmed
GUEST, unregistred user!
大侠们,我的程序是这个设想的不知能不能实现,请大侠帮忙.
我有很多FORM,如Taa,Tbb,Tcc都是继承TForm,但在程序里我动态的传类名给它就可以调用.
比如我传字符aa,bb,cc.
现在要做一个函数把接收这个字符串,在把它换成窗体类,把窗体SHOW出来,
因为我的窗体类名放在数据表里,所以要动态传输.谢谢高手指点函数写法.
 
var
mystring:tstringlist;
begin
mystring:=tstringlist.create;
mystring.add('aa');
mystring.add('bb');
mystring.add('cc');
......
case mystring.indexof(inputstring) of
1: taa.show;
2: tbb.show;
3: tcc.show;
else
showmessage('not found');
end;
 
让我先想想
 
楼上那位兄台的方法只能是预先创建好,然后再来显示。
而且效率很低,要维护那个case语句啊。
等我给你一个更好的方法。
等。。。。
 
先给你一个不是很完美的方法。
这个方法一样要预先创建,只是要方便一点。

procedure ExecForm(FormName: String);
var
form: TComponent;
begin
form := FindGlobalComponent(FormName);

if Assigned(Form) and (Form is TForm) then
begin
Form := (Form as TForm).Create(nil);
(Form as TForm).ShowModal;
(Form as TForm).Free;
end;
end;


让我再试试是否能够不创建就找到。
 
好像必须要创建才可以。
因为理论上,如果你这个form没有用到的话,它不会被编译到程序在中去的。
除非你在某个地方 create 了它。
 
当然用的form的会加入到uses中去.我有一个想法.
比如说:
vform:Tfrom;
vform:=Taa.create(self);
vform.show;
这样的话就可创建Taa的Form.现在的问题是我那个Taa是动态传送的.所以很难做到.
不知道能不能直接赋值给Vform.请大家谢谢看,我是没有试成功.

张剑波同志的方法可能不行因为这样做很烦而且不机动.
hlsl同志的方法也不行如果form多的话内存将耗掉所以不行.
 
挺有意思的问题,我看到了希望:
关键无非是在整个APPLICATION中查找ALL FORM,提示:
application.FindComponent;
application.ComponentCount;
,看看他的CLASS是什么?或这NAME是什么?,找到了。
我知道解决方案了
我肯定你也明白了

 
类的话基本上都是继承同一种.
application.FindComponent;
application.ComponentCount;
你的这种方法一定要FORM已经创建,才可以查找,可能不行.你试想想看一个系统有几十个FORM
都创建的话后果......所以只能考虑其它方法.
 
如果你的窗体在设计的时候是已经设计好的,而在程序运行的时候只是想把它调出来,可以
这样:
procedure ExecForm(FormName: String);
begin
Application.CreateForm(TFormName,FormName);
FormName.ShowModal;
FormName.Free;
end;
其中FormName是你要创建的窗体名称。
 
通过一个函数,传递对象类名参数来动态创建对象是可以实现的,但对象类名参数不是一个
简单的字串,而是一个类名指针。所以我估计用字串变量创建对象编译时不大可能实现。
类引用动态创建的例子如下:

type MyObjectName = class of TAnyObject; // 定义类引用

Procedure CallMd;
var MyObject: MyObjectName;
Obj:TAnyObject;
begin
MyObject:=Taa; // 任何TAnyObject 的子类名称 , Taa是一个对象名称而非字串
Obj:=CreateMyObject(MyObject);
end

Function CreateMyObject(TObjectName:MyObjectName):TAnyObject;
Begin
Result:=TObjectName.Create(nil);
end;

 
首先,在每个被调用FORM的UNIT单元中增加INITIALIZATION段,如果FORM的类名为TMyForm
加入
initialization
RegisterClass(TmyForm);
注册类

然后在调用窗体加入如下代码:
procedure TMainForm.OpenForm(FormClassName: string);
var
FormClass: TFormClass;
Form: TForm;
begin
FormClass:=TFormClass(GetClass(FormClassName));
Application.CreateForm(FormClass,Form);
try
Form.ShowModal;
finally
Form.Free;
end;
end;

如要打开TmyForm类的窗体则

OpForm(TmyForm);

即可
 
来晚一步
同意楼上两位

procedure TForm1.Button1Click(Sender: TObject);
var
fcName : string; // FormClass name , can be get from db as string
fcType : TFormClass; // the Form 's Type which you want create
// it can be define as follow
// TxxxFormClass = class of TxxxForm
// TxxxForm is all the forms' ancestor
f : TForm; // use for create the real form
begin
//get the string param
fcName := 'T' + dbEdit1.Text;
try
//find the correct classname
fcType := TFormClass(FindClass(fcName));
// create the form
f := fcType.Create(self);
f.Caption := f.ClassName + ' : ' + f.Name;
f.Show;
except
ShowMessage('Form Type not exist,you must register it first');
end;
end;
 
多人接受答案了。
 
后退
顶部