【问题标题】:Delphi Error: "Cannot focus a disabled or invisible window"Delphi 错误:“无法聚焦已禁用或不可见的窗口”
【发布时间】:2013-02-20 15:36:27
【问题描述】:

运行我的编译程序时出现错误。我已经采取了我能想到的所有预防措施来防止出现错误,例如在隐藏或集中它们之前启用表单。该应用程序显示DimmerForm(灰色渐变覆盖),然后在覆盖顶部显示NewFileFormNewFileForm 完成它的工作并确定要制作的文件并在MainForm 的页面控件中创建一个新的tabsheet 并显示新创建的选项卡表。到目前为止所有这些工作(我可以在NewFileForm 关闭之前中断并且发生任何错误并看到标签表已创建并成功显示)。 NewFileForm 然后关闭,它再次正常工作。

当任何东西试图将焦点设置回MainForm 时,就会发生错误。隐藏DimmerForm,或单击MainForm,或通过代码将焦点设置到MainForm,都会导致出现错误消息。将代码放在 {try, except, end} 中也不会阻止错误消息。我已经搜索了代码中可能由MainForm 的焦点触发的所有其他方法,并且在错误发生之前没有输入任何方法(因此不会导致它)。

我在以前版本的应用程序中编写了几乎完全相同的代码,然后决定从头开始对其进行重构。该应用程序的早期版本在表单聚焦方面工作顺利。

这是打开NewFileForm的代码:

procedure TMainForm.NewFilesToolButtonClick(Sender: TObject);
begin

  ShowDimmer;
  NewFileForm.ShowModal;
  HideDimmer;

end;

这是显示调光器形式的代码:

procedure ShowDimmer;
begin

  // Enable to prevent errors
  DimmerForm.Enabled := true;

  // Hide dimmer form and show mainform
  DimmerForm.Show;

end;

下面是隐藏调光表单的代码:

procedure HideDimmer;
begin

  // Enable to prevent errors
  DimmerForm.Enabled := true;
  MainForm.Enabled := true;

  // Hide dimmer form and show mainform
  DimmerForm.Hide;
  MainForm.SetFocus;

end;

【问题讨论】:

  • 尝试将您的HideDimmer 更改为DimmerForm.Hide; MainForm.Show;,别无其他。我很确定MainForm.SetFocus 是问题所在,但是您已经脱离上下文发布了三块代码,因此很难确定。 (代码不好,顺便说一句;两个独立的程序操作可见控件通常不是一个好主意。但是很难告诉你如何做得更好;同样,没有上下文。)
  • 我猜你的问题与新创建的标签页无法获得焦点有关。隔离问题并编写一个可调试的简单可重现测试。
  • 是的,显然您正试图聚焦一个禁用或不可见的窗口。错误信息很清楚。但我们可能需要一个复制品来帮助解决它。
  • 在您按下 Break on exception 查看调用堆栈面板后,您可能会看到一些事件处理程序,其中包含任何试图最后可视化控件的代码。 stackoverflow.com/search?q=exception+stack+trace+%5Bdelphi%5D 您还可以启用“使用调试 DCU”并在 VCL 内部拦截异常,在那里您可以 EvaluateInspect 尝试显示哪个对象:Self.ClassNameTComponent(Self).Name
  • 添加了 HideDimmer 和 ShowDimmer 方法用于调试,以尝试在显示和隐藏 DimmerForm 的各种场合中测试一些东西,一旦问题解决,我将摆脱它们。我确实尝试过 DimmerForm.Hide; MainForm.显示;没有喜悦。我相信问题出在新创建的标签页上。删除创建代码会停止发生错误。 TTabSheet 是在错误发生之前完全创建的,但这让我感到困惑。错误肯定会发生在创作中吗?在错误发生之前,它的任何过程都不会被调用(除了创建)。

标签: delphi delphi-xe2


【解决方案1】:

有时此错误是由 Post 事件期间数据库组件的某种活动引起的... 如果您尝试了其他任何方法,您可以尝试这个快速解决方案:将连接到数据集的数据源设置为 NIL,然后在 Post 事件完成后将其设置回来。

类似这样的:

Try
    Datasource1.DataSet := NIL;

    Try
        Query1.Post;
    Except
        On E: Exception Do
        Begin
            ShowMessage('Post error!' + #13#10 + #13#10 + E.Message);
            Exit;
        End;
    End;

Finally
    Datasource1.DataSet := Query1;
End;

【讨论】:

  • 这个答案有误,请删除!如果您在将编辑发布到数据集时收到 q 标题中的错误,则说明您的代码有其他问题导致了它。数据集Post 永远不会导致此错误。与其尝试快速解决方案,不如进行一些适当的调试并找出问题的真正原因!
  • 将数据库中的字段更改为不需要后出现此错误,但忘记读取查询组件中的字段
【解决方案2】:

Arioch 'The发表的评论中给出的解决方案

您还可以启用“使用调试 DCU”[...]

【讨论】:

  • 欢迎来到 StackOverflow!但是,这并不提供问题的答案。您可以搜索类似的问题,或参考页面右侧的相关和链接问题以找到答案。如果您有一个相关但不同的问题,请提出一个新问题,并附上指向该问题的链接以帮助提供上下文。
  • @toti08 这是一个答案,但它的形式很差。我已经编辑过了。
【解决方案3】:

通常,您将焦点调用到尚未创建的内容(在您正在创建的表单上),请尝试将一些 onCreate 代码移至 onShow。如果没有更多细节,很难判断发生了什么,但试试这个。

【讨论】:

  • 你真是个天才,我试图在onCreate 事件中专注于DBGrid,将DBGrid.SetFocus 移动到onShow 解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多