请教关于动态窗体的问题:如果我得窗体设为不是自动创建时,不能打开非自动创建的form,急!!!!  主要代码如下:
procedure TFrm_main.ListView1Click(Sender: TObject);
begin
  Frm_DM.Q_tree2.SQL.Add('select *  from h_code_tree where meno=:meno'); 
  ---
  FormName:=Frm_DM.Q_tree2.FieldByName('name').AsString;
  MyComponent:=Application.FindComponent(FormName);
  Formmeno:=MenuName(Frm_DM.Database1,Frm_DM.Model,FormName);
  if (MyComponent Is TForm) then
  begin
    try
      MyForm:=TForm(MyComponent);
      //MyForm:=TForm(MyComponent).Create(Application);
      MyForm.BorderStyle:=bsToolWindow;
      MyForm.Position:=poMainFormCenter;
      MyForm.ShowModal;
      AddLog(Frm_DM.Database1,Frm_DM.Model,Frm_login.p_username,Formmeno,Now);
    finally
      //MyForm.free;
      MyForm:=Nil;
    end;
  end
  else
  begin
    try
      //MyForm:=TForm(MyComponent).Create(Application);
      MyForm:=TForm.Create(nil);
      //MyForm.Name:=FormName;
      MyForm.BorderStyle:=bsToolWindow;
      MyForm.Position:=poMainFormCenter;
      MyForm.ShowModal;
    finally
      MyForm.free;
      MyForm:=Nil;
    end;
  end;
谢谢了!

解决方案 »

  1.   

    AddForm : TYOURForm;
    AddForm :=TYourForm.Create(self)
      

  2.   

    代码如下:
    procedure TFrm_main.ListView1Click(Sender: TObject);
    begin
      Frm_DM.Q_tree2.SQL.Add('select *  from h_code_tree where meno=:meno'); 
      ---
      FormName:=Frm_DM.Q_tree2.FieldByName('name').AsString;
      MyComponent:=Application.FindComponent(FormName);
      Formmeno:=MenuName(Frm_DM.Database1,Frm_DM.Model,FormName);
      if (MyComponent Is TForm) then
      begin
        try
          with tmycomponent.create(self) do
          begin
          MyForm:=TForm(MyComponent);
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          MyForm.ShowModal;
          end;
          AddLog(Frm_DM.Database1,Frm_DM.Model,Frm_login.p_username,Formmeno,Now);
        finally
          //MyForm.free;
          MyForm:=Nil;
        end;
      end
      else
      begin
        try
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm:=TForm.Create(nil);
          //MyForm.Name:=FormName;
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          MyForm.ShowModal;
        finally
          MyForm.free;
          MyForm:=Nil;
        end;
      end;大楷是这个意思,照这种方法试试
      

  3.   

    不报错!就是不能打开存在的form,而是创建一个新的form!
      

  4.   

    你用Application.FindComponent在Application的Components里找可能不是地方。应该在Screen.Forms里找。自己写一个For循环,比较一下窗体的名称应该就能找到。
      

  5.   

    function FindFormByName(AName: string): TForm;
    var
      I : Integer;
    begin
      Result := nil;  for I := 0 to Screen.FormCount -1 do
      begin
        if Screen.Forms[I].Name = AName then
        begin
          Result := Screen.Forms[I];
          Break;
        end;
      end;
    end;这个函数只能找到这个程序自己创建的窗体,不能用于寻找系统中运行的其他窗体。
      

  6.   

    请教关于动态窗体的问题:如果我得窗体设为不是自动创建时,不能打开非自动创建的form,急!!!!  主要代码如下:
    procedure TFrm_main.ListView1Click(Sender: TObject);
    begin
      Frm_DM.Q_tree2.SQL.Add('select *  from h_code_tree where meno=:meno'); 
      ---
      FormName:=Frm_DM.Q_tree2.FieldByName('name').AsString;
      MyComponent:=Application.FindComponent(FormName);
      Formmeno:=MenuName(Frm_DM.Database1,Frm_DM.Model,FormName);
      if (MyComponent Is TForm) then
      begin
        try
          MyForm:=TForm(MyComponent);
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          MyForm.ShowModal;
          AddLog(Frm_DM.Database1,Frm_DM.Model,Frm_login.p_username,Formmeno,Now);
        finally
          //MyForm.free;
          MyForm:=Nil;
        end;
      end
      else
      begin
        try
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm:=TForm.Create(nil);
          //MyForm.Name:=FormName;
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          MyForm.ShowModal;
        finally
          MyForm.free;
          MyForm:=Nil;
        end;
      end;
    谢谢了!
      

  7.   

    照大头鬼说的,将
    MyComponent:=Application.FindComponent(FormName);
    ->MyComponent:=FindFormByName(FormName);
      

  8.   

    你先看一下当前的窗口都叫什么名字。我很怀疑你数据库中记录的名字错了:  for I := 0 to Screen.FormCount -1 do
        ShowMessage(Screen.Forms[I].Name);
      

  9.   

    你的程序需要连接到SQL数据库,我没有条件,简单给你看了一下。
    你好象是根据窗体名称去找对应的窗体,如果有,则显示出来;如果没有,就先创建一个再显示,是不是?
    如果是这个想法,你要改一下思路:
    程序启动时,只创建最小数量的窗体(应该是DM和Main吧),其它的都是用完了就释放(Login等)。
    在主程序里用户点击ListView的时候,就新建一个,用完了就释放。
    放心,创建窗体很快,不用什么时间;这样做可以省下内存,而且代码简单。你的代码中有一些很奇怪的写法,比如:
    MyForm:=TForm(FindFormByName(FormName)).Create(Application);
    这种写法很危险,想当于把一个已存在的对象重新初始化了一次,内中的一些对象可能就重复创建了,当然,原来的也没有释放。
      

  10.   

    楼上的大侠的说的很对!
    我得程序就是根据窗体名称去找对应的窗体,如果有,则显示出来;如果没有,就先创建一个再显示。我得思路也是:只创建几个最小的窗体(如Frm_login,Frm_dm,Frm_main,别的窗体都是动态创建的),但是存在的问题是:在Frm_main中的点击ListView过程中,只要是动态创建的窗体就不会打开已经的存在的窗体,而是给我创建了一个新的窗体!下面的代码有点问题:
    procedure TFrm_main.ListView1Click(Sender: TObject);
    var
      MyForm:TForm;
      //FormName:TForm;
      MyComponent:TComponent;
    begin
      if ListView1.Selected=nil then Exit;//避免点击空白内容时报错
      Frm_DM.Q_tree2.Close;
      Frm_DM.Q_tree2.Sql.Clear;
      Frm_DM.Q_tree2.SQL.Add('select *  from h_code_tree where meno=:meno');
      Frm_DM.Q_tree2.ParamByName('meno').AsString:=ListView1.Selected.Caption;
      Frm_DM.Q_tree2.Open;
      FormName:=Frm_DM.Q_tree2.FieldByName('name').AsString;
      //Myform:= (MyComponent as TForm).Create(Application);
     MyComponent:=FindFormByName(FormName);
     { if (MyComponent Is TForm) then
      begin
         (MyComponent as TForm).ShowModal;
      end
      else
      begin
        Myform:= (MyComponent as TForm).Create(Application);
        myform.ShowModal;
      end;
      exit; }
      //
      //MyComponent:=Application.FindComponent(FormName);
      //MyForm:=TForm(MyComponent).Create(Application);
      //MyForm:=TForm(MyComponent);
      //MyForm.Show;
      if (MyComponent Is TForm) then
      begin
        try
          with mycomponent.create(self) do
          begin
          MyForm:=TForm(MyComponent);
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          Frm_ruku.ShowModal;
          end;
          AddLog(Frm_DM.Database1,Frm_DM.Model,Frm_login.p_username,Formmeno,Now);
        finally
          //MyForm.free;
          MyForm:=Nil;
        end;
      end
      else
      begin
        try
          //MyForm:=TForm(MyComponent).Create(Application);
          MyForm:=TForm.Create(nil);
          //MyForm.Name:=FormName;
          MyForm.BorderStyle:=bsToolWindow;
          MyForm.Position:=poMainFormCenter;
          MyForm.ShowModal;
        finally
          MyForm.free;
          MyForm:=Nil;
        end;
      end;end;
      

  11.   

    我明白了您的意思:可是我的窗体名称是存在库中的,如果在点击ListView1.Selected.Caption时,如果与ListView1.Selected.Caption=数据库中的窗体名称相等,则动态创建这个窗体,然后打开这个窗体!现在的问题是,虽然已经判断了ListView1.Selected.Caption=数据库中的窗体名称相等; 但是不能打开这个窗体(Frm_sys、Frm_log等), 请问怎么解决?多谢了!
      

  12.   

    不要把窗体名放在库中了,直接写在程序中:
    with ListView1.Selected do
      if Caption = ... then
        TFormA.Create(...)
      else
      if Caption = ... then
        TFormB.Create(...)
      else
        ...
      

  13.   

    你的“动态窗体”令人费解,若非在程序运行中你还会生成新的窗体类不成?:)
    给你看点新东西,愿不愿研究,你自己看着办吧:)type
      TFormClass = class of TForm;
    const
      FormClasses : array [0..1] of TFormClass = (
        TFrm_Sys, TFrm_Log
      );根据窗体名称找到窗体对应的下标,根据下标在数组中找到对应的窗体类型,这样创建窗体:
      with FormClasses[Index].Create(Application) do
      try
        ShowModal();
        ....
      finally
        Free;
      end;