我的菜单全部存在数据库里,现在点击某个菜单,就显示响应的窗体!窗体名称是从数据库里用adoquery取出来的,adoquery.fieldbyname('formname').asstring,怎么动态的创建而且显示出来啊,怎么解决

解决方案 »

  1.   

    这些窗体肯定是在建立工程的时候就已经创建好的,只不过是从自创建列表里面取消掉了而已,所以可以在菜单的单击事件中写如下代码
    begin
      if not Assigned(SomeForm) then  //假设你现在点了菜单要显示SomeForm
      begin
        SomeForm:=TForm.Create(Application);
        SomeForm.Show;
      end;
    end;同时在SomeForm的OnClose事件中写如下代码
    begin
      FreeAndNil(Self);
    end;
      

  2.   

    Sorry,忘记了,还要赋予Caption的值
    在创建后显示前,加SomeForm.Caption:=ADOQuery1.FieldValues['FormName'];
      

  3.   

    FrameSniper(§绕瀑游龙§) 你的方法我知道,现在我只是想动态的实现,就是如果想改变菜单,我只需要改变数据库里的东西,而不需要特别的编码,你这种,我每个菜单项我都要编码,明白我的意思了吗?
      

  4.   

    答案完全正确?SomeForm怎么写啊,我不知道他的具体名字,需要到数据库里查adoquery.fieldbyname('formname').asstring,然后怎么create,怎么show,你给我写写啊,如果对,马上给分!
      

  5.   

    把所有的菜单单击事件指向同一个过程,
    这个过程提取所单击的菜单的标题,作为参数赋给adoquery1中查询的参数,
    执行adoquery中的查询语句,取处相应的form的名称,
    然后someform就得到了,动态创建就行了。
      

  6.   

    知道一个对象的Name属性,如果这个对象还没有创建,我想是没有方法通过一个字串来创建特定类型的对象的!你等等,偶帮你看看!
      

  7.   

    zhangheaaa(竹) ,就是动态创建的时候出了问题,怎么写都不对,生气
    得到了someform的名称adoquery.fieldbyname('formname').asstring,以后怎么写啊
      

  8.   

    FrameSniper(§绕瀑游龙§) 你可能说到点子上了,我现在取出了窗体(单元)名称,是字符串,以后就没办法了,怎么写都不对
      

  9.   

    首先你要创建的这些窗体,必须在工程里都已经创建好,设计好了界面,
    然后将这些窗体从自创建列表中取消,表示都是动态创建,
    然后你的调用窗体的主窗体,必须uses 这些窗体的单元,
    最后你在数据库里存的都应该是窗体的name,
    那你执行 formname:=tformname.create(self);
             formname.show;
    应该是没问题了。
      

  10.   

    楼主错了,你可以把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;不就行了!!!!!!!!!!!!!!!!!!!!!!!
      

  11.   

    首先你要创建的这些窗体,必须在工程里都已经创建好,设计好了界面,
    然后将这些窗体从自创建列表中取消,表示都是动态创建,
    然后你的调用窗体的主窗体,必须uses 这些窗体的单元,
    最后你在数据库里存的都应该是窗体的name,
    --------------------------------以上都已经作好了
    adoquery.fieldbyname('formname').asstring是formname,你给我写写看看formname:=tformname.create(self);
             formname.show;
      

  12.   

    这个“我想是没有方法通过一个字串来创建特定类型的对象的!”是不正确的。完全可以实现,以下:
    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;  
      

  13.   

    var
      myform,myform_class:string;myform:=adoquery.fieldbyname('formname').asstring;
    myform_class:='T'+myform;
    tform(myform):=tform(myform_class).create(self);
    tform(myform).show;
      

  14.   

    zhangheaaa(竹) 你的方法不对吧?
      

  15.   

    to  zhangheaaa(竹) 你太想当然了,编译都过不去tform(myform_class)////////不能这样转换!
      

  16.   

    To Free007  你的方法的确不错,但里面存在一个很大的问题,即:你通过FindClass来通过一个字串返回一个类引用类型,那么字串对应的类类型必须是流系统可以识别的,所以你在使用FindClass之前必须在初始化部分注册这个类类型,但这里就出现问题了:
    假设你传递进去的的窗体名称是‘TestForm’
    那么得到的窗体类名称‘TTestForm’
    你现在要通过FindClass(‘TTestForm’);来返回指向TTestForm的类引用类型,但使用FindClass前必须对TTestForm这个类进行注册,你怎么注册呢?
    连基本的TTestForm的类申明都没有如何注册?无法注册就谈不上创建....!
      

  17.   

    to  free007(一滴蜜糖)    FindFormClass:=TFormClass(Findclass(classname));//报错,说找不到classname类。
      

  18.   

    To Yoic  他那里报错可能是他的这个代码没有自己测试过,不过思路很不错!
      那里直接使用ClassName,系统会以为是Self.ClassName,所以那里编译后是TFormClass(FindClass(Self.ClassName))而不是希望的实际ClassName,所以找不到,但即使是实际的根据传递进去的FormName组成成的ClassName,也是不可以的,因为使用FindClass的前提必须是参数字串所对应的类是已经注册过的,可以被IDE流系统识别的!所以这里要注册,但连基本的类申明都没有如何去注册呢?没有办法.....  另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)!
      

  19.   

    有个笨方法:在调用窗体单元最后加上:initialization
      ...
      RegisterClass(TForm2);  
      RegisterClass(TForm3);
      ...
    finalization
      ...
      UnRegisterClass(TForm2);
      UnRegisterClass(TForm3);
      ...
      

  20.   

    FrameSniper(§绕瀑游龙§) 你说得对,要在窗体初始的时候注册的,语句如下,呵呵,刚才忘了写initialization
    RegisterClass(TForm);
      

  21.   

    to fs//////////////////////////////////////
    //  另外,Free007的第一个转换是完全正确的!那里仅仅是个指针类型的转换,不涉及实际
    //  对象的转换,所以完全可以!例如,我们完全可以这样写TForm(1)!
    /////////////////////////////////////同意!谢谢!
      

  22.   

    呵呵,就是yoic(我是一棵菠菜,菜,菜,菜,菜,菜,菜) 的方法了,
      

  23.   

    来晚了,
    我的做法是;建立一个Class of class
    然后定义一个基类,其它FORM从它上面继承
      

  24.   

    首先,要注册窗口类,在设计时在你需要动态创建的窗体单元注册:
    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传进去即可。
      

  25.   

    注意上面STR要加上T,如上‘TFORM3’;
      

  26.   

    To Free007  你的方法可以解决楼主这个问题!刚才偶的理解有错!
      

  27.   

    我试过一种方法,不过你必须知道你要创建窗体是什么类。
    你在FormCreate的事件中用RegisterClass([ClassName])的方法把要创建的类在主窗体里注册。
    在FormClose的事件中用UnregisterClass([ClassName])的方法把要创建的窗体释放注册。
    然后用GetClass 和 FindClass都找得到类了。
      

  28.   

    不用了,楼上Free007和那个叫老王的朋友两个人的方法就已经可以解决了!揭贴吧!