You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除TFrame后窗体失去焦点无法拖动的问题解决咨询

窗体焦点丢失问题解决

问题描述

我遇到一个窗体焦点相关问题,不确定是不是焦点问题,因为找不到可行方案。我有一个继承自TFrame的TBaseFrame类,还有一个负责显示不同框架的TFrameContainer,通过容器代码里的AddObject手动把框架加到布局中。点击Button2触发事件时,容器会移除当前框架并切换到另一个框架。关闭操作逻辑类似,但之后会出现奇怪的问题:窗体好像失去了焦点,没法拖动或关闭,必须切换到其他窗口再切回来才行。框架上可能没有任何控件。

关闭逻辑代码

procedure TFrameContainer.OnFrameClosed();
begin

  case CurrentFrame.FrameType of
    Master:
      begin

      end;
    Child:
        begin
          Holder.RemoveObject(CurrentFrame);//Remove frame here from layout
          FramesPath.Remove(CurrentFrame);

          CurrentFrame.OnClose;
          CurrentFrame.DisposeOf;

          CurrentFrame := FramesPath.Last;
          Holder.AddObject(CurrentFrame);


        end;
    ChildWindowed:
      begin
        if Assigned(ParentForm) then
          begin
            ParentForm.Close;
          end;
      end;
  end;
end;

解决方案

方法1:手动指定焦点到容器或父窗体

在切换框架完成的代码后,强制设置焦点到容器控件或父窗体,填补焦点空白:

// 在Holder.AddObject(CurrentFrame);之后添加
if Holder.CanFocus then
  Holder.SetFocus
else if Assigned(ParentForm) then
  ParentForm.SetFocus;

方法2:用Windows API强制激活窗体(仅限Windows平台)

如果方法1效果不佳,可以直接调用系统API让父窗体回到前台:

uses Winapi.Windows;

// 切换框架后添加
if Assigned(ParentForm) then
  SetForegroundWindow(ParentForm.Handle);

方法3:销毁框架前提前转移焦点

避免框架销毁时带走焦点,在销毁前先把焦点移到容器:

// 在CurrentFrame.DisposeOf;之前添加
if CurrentFrame.Focused then
  if Assigned(Holder) then
    Holder.SetFocus;

原理说明

当移除旧框架并切换到新框架时,如果新框架上没有任何可聚焦的控件,系统无法自动找到合适的焦点目标,导致窗体失去激活状态。手动指定焦点到容器或窗体本身,就能恢复窗体的可交互性(拖动、关闭等操作)。

内容的提问来源于stack exchange,提问作者GreedyCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 02:58:19