我在数据库中记录每个菜单项要打开的form名称(string)
在程序中采用动态创建form的方式打开相应的Form
问题是根据string类型的form名称如何创建相应的Form

解决方案 »

  1.   

    每一个Form 都有ClassName 的嘛,怎么不利用这个呢?举个简单点的例子:if (Form1.ClassName = strToOpen) then Form1.Show;
      

  2.   

    这种解决办法无法达到动态增加模块的效果,即:
       我在数据库中动态增加一行记录,条件是我已经存在某Form
       在不重新编译程序的条件下,不可能加入一行if语句
       如果能采用create实现的话,我就不用写那么多if语句,也无上述担心了
      

  3.   

    可以假设我要想打开的所有form都从同一个类(TFormTemp)继承而来
    我想先创建一个TFormTemp的实例
    然后将其与相应的子类(根据FormName---string确定)关联起来,这在Java中解决是比较容易的,但不知道在delphi中如何解决
      

  4.   

    var
      FormName: string;//窗体名称---------------------
    创建窗体
    YourForm := TFormTemp.Create(Self);
    YourForm.Name := FormName;
    -----------------------
    显示窗体
    try
     (FindComponent(FormName) as TFormTemp).ShowModal;
      //或者(FindComponent(FormName) as TFormTemp).Show;
    except
    end;
      

  5.   

    我在数据库中动态增加一行记录,条件是我已经存在某Form然后将其与相应的子类(根据FormName---string确定)关联起来,这在Java中解决是比较容易的,但不知道在delphi中如何解决-------------------------------------------------------原理与java里的一样.你不知道的只是语法而已.(RTTI)
    而且这个问题有很多贴子.在initialization注册这个类即可.   RegisterClass(Tform1);其它的用法就不用我说了吧.
      

  6.   

    registerclasses([Tmokuaisetfm,
      Tworkflowsetfm,
      Trlzy_mainform,
      Tfabufm,
      Tjuesefm,
      Tbeianfm,
      Tquanxianzufm,
      Tworkerfm,
      Tworkflowusersetfm,
      Tyijiaofm,
      Tdaichuli,
      Tyonghufm,
      Tstar_formfm,
      Tkeyongziduanfm,
      Tform_liuchengfm,
      Tmokuaisetfm,
      Tgzmokuaisetfm]);
      

  7.   

    with Tmyform(Tcomponent(strformname)).create(self) do begin
      caption:='xxxx';
      showmodal;
    end;
      

  8.   

    配套楼上的registerclasses加上下面几句formname:string;
    f:tform;f:=tform(FindClass(formname).create(application));
    f.show;
      

  9.   

    类类型,先查看class of的帮助,定义如下:
      TTAppBasicFormClass = class of TTAppBasicForm; //TTAppBasicForm是所有子类的父类创建form的代码如下:
    procedure ShowForm(sClassName: string);
    var
      AppFormClass: TTAppBasicFormClass;
    begin
      try
        AppFormClass := TTAppBasicFormClass(FindClass(sClassName));  //关键,父类子类化
        with AppFormClass.Create(...) do begin
        end;
      except
        ShowMessage('类型 '+sClassName+' 不存在或未注册!!!');
      end;
    end;注意,findclass函数要想找到制定的类,必须在该类所在的单元加入如下的代码,这样就不必引用该单元
    initialization
      RegisterClass(TAppTaskHostForm);finalization
      UnRegisterClass(TAppTaskHostForm);另外,需保证父类构造器和子类create函数接口一致.在java中很容易实现这个功能,delphi中有点麻烦,有问题发邮件给我[email protected]
      

  10.   

    / 弹出节点项对应的窗体
    procedure TfrmPIMS.tvPIMSMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    var
    AForm: TFormPIMS;
      APersistentClass: TPersistentClass;
      AComponentClass: TComponentClass;
    tnSelected: TTreeNode;
      pDataNode: PTDataNode;
    begin
      // 判断系统是否被锁定
      if FIsLock then begin
        ShowMessage('System has been locked !');
        Exit;
      end;  // 得到当前节点及节点值
      //tnSelected := tvPIMS.GetNodeAt(X,Y + tvPIMS.);//
      tnSelected := tvPIMS.Selected;  if tnSelected = nil then
        Exit;
      // 若节点对应的窗体名为空,返回
      pDataNode := tnSelected.Data;
      tvPIMS.Selected := nil; // 置当前选择节点为空
      if Trim(pDataNode.FormName) = '' then
        Exit;
      // 若窗体的名字为"Exit",退出系统
      if SameText(pDataNode.FormName, 'Exit') then begin
       FCanClose := True;
        Close;
        Exit;
      end;
      // 判断用户是否有权限使用
      if not pDataNode.Enable then begin
        ShowMessage('Notice: You has no right to use it !');
        Exit;
      end;
      // 根据窗体名得到类名,若类名为空,返回
      APersistentClass := GetClass('T' + pDataNode.FormName);
      if APersistentClass = nil then begin
        ShowMessage(Format('Notice: The form %s is not exist !', [pDataNode.FormName]));
        Exit;
      end;
      // 根据类名得到组件类,并依此建立窗体、调用窗体
      AComponentClass := TComponentClass(APersistentClass);
      Screen.Cursor := crHourGlass;
      AForm := AComponentClass.Create(Application) as TFormPIMS;
      try
        AForm.Execute(User.UserName);
      finally
        AForm.Free;
        Screen.Cursor := crDefault;
      end;
    end;
      

  11.   

    我帮你作了一个方法,
    其中Version1.0对MDI子窗体有用
    其中Version2.0对一般子窗体有用,
    当然由于用到了Findclass这个方法,因此你必须用RegisteClasses这个方法在调用前先一一
    注册登记.function HasExisted(ChildFormName: string): Boolean;
    var
      I:Integer;
      Com : TComponent;
    begin
     Result:=False;
     if Application.MainForm=nil then Exit;
     {$IFDEF Version2.0}
     Com := Application.FindComponent(ChildFormName);
     if (Com <> nil) and Com.InheritsFrom(TForm) then
     begin
        Result := True;
     end;
     {$ELSE}
     with Application.MainForm do
     begin
       if MDIChildCount > 0 then
       begin
          for I := MDIChildCount-1 downto 0 do
          begin
            if UpperCase(MDIChildren[I].Name) = UpperCase(ChildFormName) then
            begin
              Result := True;
              Break;
            end;
          end;
       end;
     end;
     {$ENDIF}
    end;function ShowChildForm(ChildFormName: string):TForm;
       
    ResourceString
      rsTooMoreForm='打开太多的窗体,请关掉不必要的窗体!';
    Const
      MaxCount=20;
    var
      FClass:TPersistentClass;
      Form:TForm;
    begin
       {$IFDEF Version1.0}
       //  判断子窗口是否存在
       if HasExisted(ChildFormName) then
       begin
         Form:=TForm(Application.FindComponent(ChildFormName));
         Form.Show;
         Result := Form;
         Exit;
       end;   if Application.MainForm.MDIChildCount > MaxCount then
       begin
         ShowMessage(rsTooMoreForm);
         Exit;
       end;
       {$ELSE}
       {$ENDIF}   {$IFDEF Version2.0}
       //  判断子窗口是否存在
       if HasExisted(ChildFormName) then
       begin
         Form:=TForm(Application.FindComponent(ChildFormName));
         Result := Form;
         Exit;
       end;   {$ELSE}
       {$ENDIF}   FClass := GetClass('T'+ChildFormName);
       Form:=TFormClass(FClass).Create(Application);   {$IFDEF Version1.0}
          Form.WindowState:= wsMaximized;
           Form.Show;
       {$ELSE}
       {$ENDIF}   Result := Form;
    end;
      

  12.   

    使用Application.CreateForm方法,在工程文件中就有使用的例子。
      

  13.   

    jabmoon(刺月)
    楼主的想法和我原来的想法是一样的,动态增加模块是不是想控制某些用户的使用权限?我使用的方法是在数据表中记录窗体名,然后依次创建
    你错了,楼主的想法重点是在动态追加功能模块。其实楼主,我还有种方法不知你想不想试试。
    把你的各模块窗体做到DLL中。
    然后在各DLL中都有一个共同的接口。
    程序初始化时,搜索指定路径中的各个DLL尝试调用共同的过程。
    如果调用成功就返回窗体DLL中名称(失败就说明其並非其模块)。
    再可将DLL名称加入菜单。
    当然这个菜单的功能就是调用对应的DLL窗体。完成他的功能操作。
    我以前看过有这么个例子,我说的只是这么一个过程。具体的忘了。呵呵。
      

  14.   

    楼主请看;请在mainForm 中引用要建立的两个窗体,uses 部分加入即可;uses Unit2, Unit3;{$R *.dfm}
    //这里是根据类建立窗体
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      with TFormClass(FindClass('TForm2')).Create(Application) do
        try
          ShowModal;
        finally
          Free;
        end; 
    end;///这里是注册你要动态建立的所有窗体类,必须注册,否则找不到的
    initialization
      RegisterClasses([TForm2,TForm3]);
    end.