【问题标题】:How to know which Form is opened and how to close it?如何知道打开了哪个表单以及如何关闭它?
【发布时间】:2018-02-26 13:16:46
【问题描述】:

我的主窗体触发了一个TAction.OnExecute 事件处理程序, FormPrincipal,打开其他表单。

procedure TFormPrincipal.AbreFormBancoExecute(Sender: TObject);
begin
   Formbanco              := Tformbanco.Create(self);
   Formbanco.Parent       := PanelCorpo;
   Formbanco.Align        := alclient;
   Formbanco.BorderIcons  := [];
   Formbanco.Show;
   Formbanco.BorderStyle  := bsNone;
   Formbanco.SetFocus;
end;

一旦我有几个表单,在触发OnExecute打开另一个表单之前,如何知道打开了哪个以及如何关闭它?

=========== 终于可以正常工作了======= 主要形式是form1,我称之为form2和form3。在 form1 中,我有一个 panel1,它是 form2 和 form3 的父级。请参阅 form1 代码: ... 变量 Form1:TForm1;

implementation
{$R *.dfm}
uses unit2, unit3;

procedure Tform1.CloseActiveForm (Formname : string);
// Free memory allocated to the current form , set it to nil
// I'll have to find a better way to perform FreeanNil without
// use many IFs command
begin
     if Formname  = 'form2' then FreeAndnil(Form2) else
         if Formname = 'form3' then FreeandNil(Form3);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
       CloseActiveForm(Edit1.Text); //Edit1 has the current active form name
       if form2 = nil  then
       begin
              Application.CreateForm(Tform2,Form2);
              Form2.Parent  := Panel1;
              Form2.Align   := alclient;

              Form2.Show;
              Form2.BorderStyle :=  bsnone;
              Form2.SetFocus;
              Form2.OnActivate(Sender); //Method Show blocks Activate event
      end;    
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
       CloseActiveForm(Edit1.Text); //Edit1 has the current active form name
       if form3 = nil  then
        begin
              Application.CreateForm(Tform3,Form3);
              Form3.Parent  := Panel1;
              Form3.Align   := alclient;

              Form3.Show;
              Form3.BorderStyle := bsnone;
              Form3.SetFocus;
              Form3.OnActivate(Sender);  //Method Show blocks Activate event             
        end;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
   Edit1.Text := Screen.ActiveForm.Name;
end;
end.

2) form2和form3中的代码(认为form3是相同的)

...

var
  Form2: TForm2;

implementation

{$R *.dfm}
uses unit1;

procedure TForm2.Button1Click(Sender: TObject);
begin
       Edit2.Text := Screen.ActiveForm.Name;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
     setfocus;
     Edit1.Text       := Form2.Name;
     Form1.Edit1.Text := Form2.Name; //set form name 

// the property Screen.ActiveForm.Name if used here, will always presents
// form1 name (main form) because this form2 is set to a parent panel 
// in form1
end;  

end.

【问题讨论】:

  • Screen.Forms 是一个索引属性,您可以通过它访问现有表单。
  • 如果你只是想防止TFormBanco的多个实例,在调用TFormBanco.Create()之前检查你的Formbanco变量是否为零,当表单被销毁时,让它的OnDestroy事件重置变量为零。您可以通过将事件的Action 参数设置为caFree 来让Form 的OnClose 事件触发销毁。
  • 这段代码真的搞混了,你能告诉我们你为什么要使用表单来完成这个特定的任务吗?你真正想做的是什么?
  • 发布编辑作为答案@jrg
  • Nasreddine,我的目标是有一个主表单(form1)调用其他表单(form2,form3,form-n),并在表单1的面板中显示被调用的表单。我将使用带有 Tbuttons 的 Ttoolbar,每个表单一个来执行调用。在打开每个表单之前,我必须保证当前活动的一个将被关闭和释放,以避免同一表单的多个实例。还有其他方法可以实现吗?即在主要表单的面板内打开多个表单?如果是这样,请帮助 e 了解这一点。感谢您的支持。

标签: forms delphi events delphi-10.2-tokyo


【解决方案1】:

如果表单存在,则销毁它并创建它的新实例。

procedure TFormPrincipal.AbreFormBancoExecute(Sender: TObject);

  procedure CreateFormbanco;
    begin
    Formbanco               := TFormbanco.Create(self);
    Formbanco.Parent       := PanelCorpo;
    Formbanco.Align        := alclient;
    Formbanco.BorderIcons  := [];
    Formbanco.BorderStyle  := bsNone;
    Formbanco.Show;
    Formbanco.SetFocus;
    Formbanco.OnDestroy    := FormDestroyEvent;
    end;

begin
if not Assigned(Formbanco) then
  begin
  CreateFormbanco;
  end
else
  begin
  Formbanco.Destroy;
  CreateFormbanco;
  end;

procedure TFormPrincipal.FormDestroyEvent(Sender: TObject);
begin
  Formbanco := nil;
end;

此代码将检查Formbanco 是否存在,如果存在则将其销毁并创建一个新实例,否则将创建一个新实例。

编辑: 创建不同的表单并使用上面的代码,只需将 FormbancoTFormbanco 更改为他们尊重的新表单名称。

【讨论】:

  • 此代码扫描所有现有的表单以获取可见的表单。是否有可能在不扫描所有这些的情况下知道哪个是可见和激活的(聚焦)?我尝试使用 Screen.Activeform.Name 但它只返回调用者表单,而不是由 OnExecute 代码中触发的事件打开的表单(如上)。它有什么问题?
  • 但它只返回调用者表单 这取决于你如何调用它。请不要告诉我这是通过您的表单主体中的按钮单击
  • 我检查并实现了 [Delphi - Capturing the Window/Form which has current focus] ,此代码在关闭应用程序后导致异常。我没有使用 MDI,代码似乎是为 MDI 程序编写的。
  • 此时,为了理解调用者/被调用表单的机制,我将调用放在了一个 Button 中,但是一旦我了解它是如何工作的,我就会在 TAc​​tion 中对其进行编码并使用 Tmenu .从按钮调用有什么限制吗?
猜你喜欢
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
相关资源
最近更新 更多