有朋友和我讨论过,已经知道一个类名,怎么才能创建一个实列。一个偶然的机会发现很好做。
用Tform来做个试验吧。
   1、新建工程,主form为form1,保存为unit1,添加一个form2,保存为unit2。
   2、 在unit2中TForm2 = class(TForm)前面加上 
          TmyForm = class of Tform2;//相当于给Tform2加上一个别名
   3、 在form1的FormCreate中写入RegisterClasses([TForm2]);//注册Tform2类
   4、 在form1的button的单击事件中加入
         var 
              A : Tform ;
         begin
           if GetClass('TForm2') =nil then exit ;
           a := TMyform(GetClass('TForm2')).Create(nil);
           a.show;
         end;
        搞定! 
当然很多情况下,大家不会这样做。不过也可以试验一下。
比如,我有很多地方都需要调用各种的参数配置对话框,然而,我想偷懒,不想写太多的代码。我就可以通过发自定义消息的办法。先将所有的对话框类名写入一个数组中去。在需要调用的参数配置对话框的时候,发一个消息。接收消息的模块,就通过他发送过来的值,比如是一个int类型的id,我可以根据这个id在数组中找到类名,然后用上面的方法就可以搞定了。当然就节约了很多的代码了。
-----------------
欢迎讨论

解决方案 »

  1.   

    4、 在form1的button的单击事件中加入
             var 
                  A : Tform ;
             begin
               if GetClass('TForm2') =nil then exit ;
               a := TMyform(GetClass('TForm2')).Create(nil);
               a.show;
             end;
    上面的这段代码对另外的Form,如form3也能用吗?
      

  2.   

    TmyForm = class of Tform2
    也可以改成Tform2的父类
    TmyForm = class of Tform,效果是一样的
      

  3.   

    可以,有用。只要form3被注册了就可以。
      

  4.   

    :)
    的确还没有试过,不过VC MFC RTTI里面有GetObject可以达到这种要求,delphi的RTTI应该不比VC弱才对阿
      

  5.   

    算不算使用rtti的例子
    不过
      3、 在form1的FormCreate中写入RegisterClasses([TForm2]);//注册Tform2类
    对TForm2类有什么要求,只要uses包含这个类的unit就可以了吗
      

  6.   

    贴一段代码给大家看看function THWDataSetProvider.DoDBProcess(LPName, MethodName, LParam,
      WParam: string): Integer;
    type
      THWLPClass = class of THWLogicProcessor;
    var
      aHWLPClass: THWLPClass;
      bHWLPClass: THWLogicProcessor;
    begin
      aHWLPClass := THWLPClass(FindClass(LPName));
      bHWLPClass := aHWLPClass.Create;
      try
        bHWLPClass.Provider := Self;
        bHWLPClass.DBAccess := ServerDBAccess;
        Result := bHWLPClass.Execute(MethodName, LParam, WParam);
      finally
        bHWLPClass.Free;
      end;
    end;中间层封装业务逻辑的例子,LPName是业务逻辑的功能unit,MethodName是unit中的函数, LParam, WParam是参数.和楼主差不多的例子,不过registerclasses我还是觉的写在类单元里比较好
    具体的技术我不太清楚,听大家讨论~~
      

  7.   

    个人认为这样的坐法没有什么意义,只是用为学习。学习。。FForm : TForm;
    ...
    Property vForm : TForm Read FNext Write FNext;...
    var
      Form1 : TForm1;
    implementation
    Uses
      Unit2;
    ...
    ....
    Procedure TForm1 -> Button OnClick(Sender : TObject);
    begin
      if Assigned(FForm) then
        TForm2(FForm).Show;
    end;
    Program Project1
    uses
      .....begin
      Application.Initialize;
      .........
      Form1.vForm := Form2; 
      Application.Run;
    end.
    ----------------
    沉沦中..........
      

  8.   

    ……
    RegisterClasses([TForm_ManWellInfo_Mode,TForm_Pole_Mode,TForm_Pipe_Mode,
      TForm_ExBox_Mode,TForm_SubBox_Mode,TForm_LCable_Mode]);
    ……
    procedure TBasic_Form.Bbtn_OpenModeClick(Sender: TObject);
    var
      sModeName:string;
      FormClass: TFormClass;
      FormObject: TObject;
    begin
      sModeName:=Self.Name+'_Mode';
      FormClass := TFormClass(GetClass(sModeName));
      FormObject := FormClass.Create(nil);
      TForm_Basic_Mode(FormObject).ShowModal;
    end;
      

  9.   

    最好这样TmyForm = class of Tform通用性强
      

  10.   

    TmyForm = class of Tform
    这个在delphi里面就是TFormClass = class of TForm;  在 Forms单元里面有的定义。RegisterClasses的方便就是它能在已知类的名称(字符串)的情况下用GetClass方法,得到类。但是通常这个可以回避。
    下面是我在MDI程序里避免一个窗口被多次创建的代码用到了 TFormClass.function TFrmMain.ShowMDIChildWindowEx(ClsFrm: TFormClass;
      bRestore: boolean): boolean;
    var
      i: integer;
      frm: TForm;
    begin
      result:= false;
      frm:= nil;
      for i:=0 to self.MDIChildCount-1 do
        if (Self.MDIChildren[i].ClassNameIs(ClsFrm.ClassName)) then begin
          frm:= Self.MDIChildren[i];
          break;
        end;
      try
        if (frm = nil) then begin
          frm:= ClsFrm.Create(self);
          if self.MDIChildCount <= 1 then
            frm.WindowState:= wsMaximized;
        end;  // end of if
        with frm do begin
          if (bRestore) then begin
            if (WindowState = wsMinimized) then
              WindowState:= wsNormal;
          end;
          Show;
        end;
        Result:= true;
      except
        on E: Exception do
          MessageBox(0, pchar('错误。'#10#13'' + E.Message),'', MB_ICONERROR);
      end;
    end;
    使用方法
    procedure TFrmMain.actSLogManagerExecute(Sender: TObject);
    begin
      ShowMDIChildWindowEx(TFrmLogManager, true);
    end;
      

  11.   

    type
    a:TForm2;
    end;
    a:=TForm2.create(nil);
    a.show;