Delphi 12中停靠窗体时触发"Cannot Focus a Disabled or Invisible Window"错误求助
问题
主窗体包含Panel控件,已将其DockingSite设为True;点击主窗体按钮可创建第二个窗体(内含按钮与编辑框),第二个窗体的按钮点击事件执行ActiveControl := Edit1;。
- 未停靠时,点击第二个窗体按钮可正常将焦点设为Edit1;
- 在主窗体按钮代码中添加
fm.ManualDock(Panel1)后,点击第二个窗体按钮触发错误:Cannot Focus a Disabled or Invisible Window。
该现象与将第二个窗体Parent设为Panel1时的预期一致,请问窗体停靠本质是否和设置Parent效果相同?
出错代码
procedure TForm1.Button1Click(Sender: TObject); var fm : TForm; begin fm := TForm2.Create(Self); fm.ManualDock(Panel1); fm.Show; end;
正常代码
procedure TForm1.Button1Click(Sender: TObject); var fm : TForm; begin fm := TForm2.Create(Self); //fm.ManualDock(Panel1); fm.Show; end;
分析与解答
窗体停靠与设置Parent的本质关联
通过ManualDock实现窗体停靠,核心逻辑就是修改窗体的Parent属性。当你调用fm.ManualDock(Panel1)时,目标窗体的Parent会被自动设置为Panel1,它从独立的顶级窗口变成了Panel1的子控件——这和手动执行fm.Parent := Panel1的核心效果完全一致。错误触发的原因
当窗体成为Panel的子控件后,它的窗口特性会发生关键变化:
- 子窗体不再是拥有独立焦点管理的顶级窗口,系统的焦点控制权归属于主窗体(顶级窗口)。
- 此时直接在子窗体中执行
ActiveControl := Edit1,相当于尝试让非顶级窗口的控件获取焦点,系统会判定该子窗体属于“无法获取焦点的窗口”,从而抛出Cannot Focus a Disabled or Invisible Window错误。
- 可行的解决方式
要在停靠后的窗体中为Edit1设置焦点,可直接调用控件的SetFocus方法,绕过子窗体的ActiveControl设置:
// 替换原按钮点击事件中的ActiveControl代码 Edit1.SetFocus;
或者先确保主窗体处于激活状态,再设置焦点:
Form1.Active := True; Edit1.SetFocus;
内容的提问来源于stack exchange,提问作者PeerYog
相关产品推荐
相关产品推荐

