这些窗体肯定是在建立工程的时候就已经创建好的,只不过是从自创建列表里面取消掉了而已,所以可以在菜单的单击事件中写如下代码 begin if not Assigned(SomeForm) then //假设你现在点了菜单要显示SomeForm begin SomeForm:=TForm.Create(Application); SomeForm.Show; end; end;同时在SomeForm的OnClose事件中写如下代码 begin FreeAndNil(Self); end;
楼主错了,你可以把fs的那段代码写成一个公有函数,把菜单的caption作为参数进行传递,怎么会每个菜单都要写代码呢???你说someform怎么写,那你就要问你自己了,你创建的菜单你不会不知道他有个caption属性吧,someform当然就可以传给someform了,你问怎么create,怎么show,你连create、show都不会写????someform:=adoquery.fieldbyname('formname').asstring begin if not Assigned(SomeForm) then //假设你现在点了菜单要显示SomeForm begin SomeForm:=TForm.Create(Application); SomeForm.Caption:=ADOQuery1.FieldValues['FormName']; SomeForm.Show; end; end;同时在SomeForm的OnClose事件中写如下代码 begin FreeAndNil(Self); end;不就行了!!!!!!!!!!!!!!!!!!!!!!!
这个“我想是没有方法通过一个字串来创建特定类型的对象的!”是不正确的。完全可以实现,以下: function TMainForm.FindForm(FormName,FormCaption: string): TForm; var FindForm:TForm; FindFormClass:TFormClass; classname:string;//窗体类名 begin FindForm:=tform(FormName); classname:='T'+formname; FindFormClass:=TFormClass(Findclass(classname)); if FindFormClass<>nil then begin application.Createform(FindFormClass,FindForm); FindForm.Caption:=FormCaption; result:=FindForm; end; end;
var myform,myform_class:string;myform:=adoquery.fieldbyname('formname').asstring; myform_class:='T'+myform; tform(myform):=tform(myform_class).create(self); tform(myform).show;
zhangheaaa(竹) 你的方法不对吧?
to zhangheaaa(竹) 你太想当然了,编译都过不去tform(myform_class)////////不能这样转换!
To Free007 你的方法的确不错,但里面存在一个很大的问题,即:你通过FindClass来通过一个字串返回一个类引用类型,那么字串对应的类类型必须是流系统可以识别的,所以你在使用FindClass之前必须在初始化部分注册这个类类型,但这里就出现问题了: 假设你传递进去的的窗体名称是‘TestForm’ 那么得到的窗体类名称‘TTestForm’ 你现在要通过FindClass(‘TTestForm’);来返回指向TTestForm的类引用类型,但使用FindClass前必须对TTestForm这个类进行注册,你怎么注册呢? 连基本的TTestForm的类申明都没有如何注册?无法注册就谈不上创建....!
to free007(一滴蜜糖) FindFormClass:=TFormClass(Findclass(classname));//报错,说找不到classname类。
To Yoic 他那里报错可能是他的这个代码没有自己测试过,不过思路很不错! 那里直接使用ClassName,系统会以为是Self.ClassName,所以那里编译后是TFormClass(FindClass(Self.ClassName))而不是希望的实际ClassName,所以找不到,但即使是实际的根据传递进去的FormName组成成的ClassName,也是不可以的,因为使用FindClass的前提必须是参数字串所对应的类是已经注册过的,可以被IDE流系统识别的!所以这里要注册,但连基本的类申明都没有如何去注册呢?没有办法..... 另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)!
to fs////////////////////////////////////// // 另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际 // 对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)! /////////////////////////////////////同意!谢谢!
呵呵,就是yoic(我是一棵菠菜,菜,菜,菜,菜,菜,菜) 的方法了,
来晚了, 我的做法是;建立一个Class of class 然后定义一个基类,其它FORM从它上面继承
首先,要注册窗口类,在设计时在你需要动态创建的窗体单元注册: initialization RegisterClass(TForm3); 然后如下: procedure Tform1.ShowForm(str:string); var fmname:TForm; begin if GetClass(str)<>nil then begin fmname:=TFormClass(FindClass(str)).Create(self); fmname.show; end; end;然后直接把STR传进去即可。
begin
if not Assigned(SomeForm) then //假设你现在点了菜单要显示SomeForm
begin
SomeForm:=TForm.Create(Application);
SomeForm.Show;
end;
end;同时在SomeForm的OnClose事件中写如下代码
begin
FreeAndNil(Self);
end;
在创建后显示前,加SomeForm.Caption:=ADOQuery1.FieldValues['FormName'];
这个过程提取所单击的菜单的标题,作为参数赋给adoquery1中查询的参数,
执行adoquery中的查询语句,取处相应的form的名称,
然后someform就得到了,动态创建就行了。
得到了someform的名称adoquery.fieldbyname('formname').asstring,以后怎么写啊
然后将这些窗体从自创建列表中取消,表示都是动态创建,
然后你的调用窗体的主窗体,必须uses 这些窗体的单元,
最后你在数据库里存的都应该是窗体的name,
那你执行 formname:=tformname.create(self);
formname.show;
应该是没问题了。
begin
if not Assigned(SomeForm) then //假设你现在点了菜单要显示SomeForm
begin
SomeForm:=TForm.Create(Application);
SomeForm.Caption:=ADOQuery1.FieldValues['FormName'];
SomeForm.Show;
end;
end;同时在SomeForm的OnClose事件中写如下代码
begin
FreeAndNil(Self);
end;不就行了!!!!!!!!!!!!!!!!!!!!!!!
然后将这些窗体从自创建列表中取消,表示都是动态创建,
然后你的调用窗体的主窗体,必须uses 这些窗体的单元,
最后你在数据库里存的都应该是窗体的name,
--------------------------------以上都已经作好了
adoquery.fieldbyname('formname').asstring是formname,你给我写写看看formname:=tformname.create(self);
formname.show;
function TMainForm.FindForm(FormName,FormCaption: string): TForm;
var
FindForm:TForm;
FindFormClass:TFormClass;
classname:string;//窗体类名
begin
FindForm:=tform(FormName);
classname:='T'+formname;
FindFormClass:=TFormClass(Findclass(classname));
if FindFormClass<>nil then
begin
application.Createform(FindFormClass,FindForm);
FindForm.Caption:=FormCaption;
result:=FindForm;
end;
end;
myform,myform_class:string;myform:=adoquery.fieldbyname('formname').asstring;
myform_class:='T'+myform;
tform(myform):=tform(myform_class).create(self);
tform(myform).show;
假设你传递进去的的窗体名称是‘TestForm’
那么得到的窗体类名称‘TTestForm’
你现在要通过FindClass(‘TTestForm’);来返回指向TTestForm的类引用类型,但使用FindClass前必须对TTestForm这个类进行注册,你怎么注册呢?
连基本的TTestForm的类申明都没有如何注册?无法注册就谈不上创建....!
那里直接使用ClassName,系统会以为是Self.ClassName,所以那里编译后是TFormClass(FindClass(Self.ClassName))而不是希望的实际ClassName,所以找不到,但即使是实际的根据传递进去的FormName组成成的ClassName,也是不可以的,因为使用FindClass的前提必须是参数字串所对应的类是已经注册过的,可以被IDE流系统识别的!所以这里要注册,但连基本的类申明都没有如何去注册呢?没有办法..... 另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)!
...
RegisterClass(TForm2);
RegisterClass(TForm3);
...
finalization
...
UnRegisterClass(TForm2);
UnRegisterClass(TForm3);
...
RegisterClass(TForm);
// 另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际
// 对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)!
/////////////////////////////////////同意!谢谢!
我的做法是;建立一个Class of class
然后定义一个基类,其它FORM从它上面继承
initialization
RegisterClass(TForm3);
然后如下:
procedure Tform1.ShowForm(str:string);
var
fmname:TForm;
begin
if GetClass(str)<>nil then
begin
fmname:=TFormClass(FindClass(str)).Create(self);
fmname.show;
end;
end;然后直接把STR传进去即可。
你在FormCreate的事件中用RegisterClass([ClassName])的方法把要创建的类在主窗体里注册。
在FormClose的事件中用UnregisterClass([ClassName])的方法把要创建的窗体释放注册。
然后用GetClass 和 FindClass都找得到类了。