DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: lijian100
今日帖子: 2
在线用户: 1
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 21968578 (咪咪糊糊) ★☆☆☆☆ -
普通会员
2022/6/22 1:15:40
标题:
怎么关闭用字符串传递名称的窗体 浏览:547
加入我的收藏
楼主: 我需要用字符串传递窗体名称,并且关闭它(这些窗体是由系统已经自动创建好了的,无需再次手动创建)

以下网上的代码可以用字符串方式打开form2的,但是我的form2已经无需再次创建了,并且我需要的是关闭,请问要怎么写呢?

var
    aform:TForm;
begin
    aform:=TFormClass(FindClass('TForm2')).Create(Application);
    aform.ShowModal;
end;


下面我改过的写法,行不通。

var
    aform:TForm;
begin
    aform:=TForm(TFormClass(FindClass('TForm2')));
    aform.close;
end;
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
注册会员
2022/6/22 4:55:14
1楼: try my sample:

IMPORTANT: use "TRY EXCEPT block" to avoid "xForm = NIL" for example!!!
----------
var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  x         : TForm;
  MyArrForms: TArray<TForm>;

procedure MyCloseMyFormNamed(AFormName: string);
begin
  if not AFormName.IsEmpty then
    for var i: integer := 0 to (Screen.FormCount - 1) do
      if Screen.Forms[i].Name = AFormName then // or... Screen.Forms[i].Caption = 'the caption form' ...
      begin
        if not(Screen.Forms[i] = Application.MainForm) then

          Screen.Forms[i].Close;
        //
        exit;
      end;
end;

procedure MyCloseMyForm(AForm: TCustomForm);
begin
  if not(AForm = nil) then
    for var i: integer := 0 to (Screen.FormCount - 1) do
      if Screen.Forms[i] = AForm then
      begin
        Screen.Forms[i].Close;
        //
        exit;
      end;
end;

procedure MyCloseMyArrForm(AForms: TArray<TForm>);
begin
  for var i: integer := 0 to high(AForms) do // dont close the "form in use"... form1...calls form2... calls form3
  begin
    if not((AForms[i] = Application.MainForm) { or AForms[i]= .... } ) then
      AForms[i].Close;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyArrForms := MyArrForms + [Form1, x];
  //  MyArrForms := MyArrForms + [x, Form1];  <--- last to first OK!
  //
  // MyCloseMyFormNamed('Form1');
  //
  // MyCloseMyForm(x);
  //
  MyCloseMyArrForm(MyArrForms);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  x := TForm.Create(Application);
  x.Show;
end;

end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/6/22 10:00:45
2楼: 如果你的 Form 都是 Create(Application) 的,那么,它的 Owner 就是 Application

因此,对 Application 这个对象的 Components[i] 就会是这个 Form,下面的代码可以找到你要的 Form。既然找到,当然可以关闭。

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for I := 0 to Application.ComponentCount -1 do
  begin
    if (Application.Components[i] is TForm) then
    begin
      Memo1.Lines.Add(Application.Components[i].Name);
    end;
  end;
end;
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
注册会员
2022/6/22 10:53:30
3楼: better would be "always" search it in "Screen" object, because the forms (hide or not) it will be there. Include "DataModules"...


implementation

{$R *.dfm}

uses
  System.StrUtils;

var
  a, b, c, d: TForm;

procedure TForm1.Button1Click(Sender: TObject);
begin
  for var i: integer := 0 to (Screen.FormCount - 1) do
    Memo1.Lines.Add(          { }
      Screen.Forms[i].Name + ', ' +          { }
      Screen.Forms[i].ToString { if "Name=empty" } + ', ' + { }
      IntToStr(Screen.Forms[i].Handle) + ', ' +          { }
      IfThen(Screen.Forms[i].Showing, 'Showing', 'Hide')    { }
      );

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  a := TForm.Create(Application);
  b := TForm.Create(self);
  //
  b.Hide; // by default if not "Show/ShowModal" called
  //
  c := TForm.Create(nil);
  d := TForm.Create(a);
end;

end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/6/22 13:06:46
4楼: 下面我改过的写法,行不通。

var
    aform:TForm;
begin
    aform:=TForm(TFormClass(FindClass('TForm2')));
    aform.close;
end;

 aform:=TForm(TFormClass(FindClass('TForm2')));
这句只是找到了这个类类型,没创建实例,怎么关闭。

不要考虑那么复杂,form关闭方式和显示模式有关,
模态方式:
try
   aform.ShowModal;
finally
   aform.free;
end;
非模态方式:
try
  aform.Show;
except
  //这里处理异常
end;
aform.close不一定释放了,取决于
TCloseAction = (caNone, caHide, caFree, caMinimize);
只有caFree,close才是真正释放
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
注册会员
2022/6/22 17:30:55
5楼: FindClass('TForm2'))能工作的前提, 是在Form2的单元加上

initialization
  RegisterClass(TForm2);
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/6/22 18:24:22
6楼: @ bluestorm8 (bluestorm)
大侠,他这种情况不用注册....
Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. Other classes can be registered by calling RegisterClass or RegisterClasses. 

帮助里有说的
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
注册会员
2022/6/23 8:54:52
7楼: 如果不注册,下面的代码会报错: Class TForm2 not Found.
procedure TForm1.FormShow(Sender: TObject);
var
  formClass: TFormClass;
begin
  formClass := TFormClass(FindClass('TForm2'));
end;

==========另附project source==========
:
program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/6/23 11:04:42
8楼: 测试了一下,不注册会报错。
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
注册会员
2022/6/23 13:36:02
9楼: aform:=TForm(TFormClass(FindClass('TForm2')));
这种写法是肯定错误的, 因为TForm是TFormClass的Object, 不是同一级别的东西, 就像aform和TForm不是同一级别一样.
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/6/23 17:45:08
10楼: 。。。
我搞错了,TForm还是要注册的,只是TForm上的组件实例(设计拖拉下来的组件)不用注册。动态生成的组件也要注册。
----------------------------------------------
-
作者:
男 letianwuji (大器晚成) ▲▲▲▲△ -
注册会员
2022/6/23 18:16:04
11楼: 你这其实想要调用子窗体的代码。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行42.96875毫秒 RSS