【问题标题】:Closing a secondary delphi form causes the main form to lose focus关闭辅助 delphi 窗体会导致主窗体失去焦点
【发布时间】:2010-12-26 05:07:11
【问题描述】:

当从主窗体显示次要窗体,从第二个窗体显示第三个窗体然后关闭这两个窗体将导致主窗体失去焦点。

在 XP SP3 中使用 Delphi 2009

这是我重现问题的步骤:

  1. 创建新的 VCL 表单应用程序
  2. 将按钮拖到创建的表单上
  3. 在点击处理程序中创建一个新的 TForm1 并显示它

运行程序。单击按钮以显示第二个表单。单击第二个表单上的按钮以创建第三个表单。当关闭两个新窗体时,主窗体将失去焦点。

这是我在按钮单击事件处理程序中的代码:

// 使用 Self 不会改变结果 用 TForm1.Create(nil) 做 显示;

有什么方法可以阻止我的主窗体失去焦点?

【问题讨论】:

  • 你的问题到底是什么?为什么会发生这种情况?或者如何规避这个问题?
  • 后者。 (我也不介意知道前者)
  • 尝试将 nil 参数设置为 self。
  • 在 Create 方法中使用 Self 不会改变结果
  • 使用 Self 作为 Owner 至少可以避免内存泄漏……但这是另一个问题。

标签: delphi winapi delphi-2009 vcl


【解决方案1】:

在将我的 Delphi 安装从版本 12.0.3170.16989(无更新) 升级到版本 12.0.3420.21218(更新 3 和 4) 后,我无法再重现该问题。

似乎这是更新中修复的错误。

【讨论】:

    【解决方案2】:

    我不明白您所描述的如何创建“子”表单。

    但无论如何,我只是按照您在步骤中描述的内容进行了尝试,并且无法在 D2009(更新 3 和 4)中重现它,无论我是从主表单还是从第一个“孩子”创建第二个“孩子” ,以及我关闭它们的顺序。

    所以,肯定还有什么你没有告诉的……

    【讨论】:

    • 最重要的是,参数中的nil设置了父窗体,所以没有父窗体,所以不是子窗体...
    • @mj2008:不,它没有设置父级。 Create() 的参数是 owner,这使得它负责释放表单。这与出身无关。
    • 我在不止一台机器上进行了尝试,结果相同。你用的是什么版本的Delphi?我只能在 Delphi 2009 中重现它,而不是在 Delphi 7 中
    • 已更新为 Delphi 版本。 (D2009,更新 3 和 4)
    • 我认为我没有安装任何 Delphi 更新。这是我的确切版本号 12.0.3170.16989 我在 3 台机器上安装了这个版本,结果相同。你的版本更高吗?
    【解决方案3】:

    从纯 Win32 的角度来看,当弹出窗口关闭时,应用程序往往会失去焦点,因为底层框架存在操作顺序问题。 Windows 不会激活禁用的窗口,因此,在销毁模式弹出窗口时,在弹出窗口调用 DestroyWindow 之前(重新启用)父窗口非常重要。

    我不知道这如何适用于 delphi 或 vcl 的开发。代码示例并不意味着您对模式弹出窗口的销毁方式有很多或任何控制权。

    【讨论】:

    • 请注意,问题是关于关闭非模态子窗口。
    【解决方案4】:

    尝试以下方法(并避免使用 with):

    with TForm1.Create(nil) do begin
      show;
      activate;
      bringtofront;
    end;
    

    【讨论】:

    • 不改变结果。你能在你的机器上重现它吗?
    【解决方案5】:

    与 François 一样,我无法在 Windows XP SP3 上使用 Delphi 2009 重现此行为。关闭其他表单后,首先打开的表单将重新获得焦点。

    可以肯定的是,你的项目代码是:

    program Project1;
    
    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1};
    
    {$R *.res}
    
    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
    

    还有你的单位代码:

    unit Unit1;
    
    interface
    
    uses
      Forms, Classes, Controls, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      with TForm1.Create(nil) do
        Show;
    end;
    
    end.
    

    更正了弗朗索瓦的名字,抱歉

    【讨论】:

    • 和上面的代码一模一样!我的版本是12.0.3170.16989 你是哪个版本的?
    • 我的版本是12.0.3420.21218。
    • 只是一个疯狂的猜测,但您是否可以运行一些其他应用程序来吸引焦点?
    猜你喜欢
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多