【问题标题】:Focus control after form is shown显示表单后的焦点控制
【发布时间】:2016-07-09 04:11:31
【问题描述】:

我有一些表格可以帮助我搜索产品或客户。当我打开这些表单时,我希望输入用于搜索的 TEdit 控件成为焦点。为此,我一直在使用 Timer,但我一直在寻找一种更合法的方法来执行此操作,因为如果在表单尚不可见时告知控件聚焦,这有时会导致错误。

我尝试使用在窗体的 OnShow 事件结束时调用的 Windows 消息 AfterShow。它不像 ActiveControl 或 SetFocus 的其他更简单的解决方案那样工作。窗口消息代码是这样的。

const WM_AFTER_SHOW = WM_USER + 444;
  private
    procedure WmAfterShow(var Msg: TMessage); message WM_AFTER_SHOW;

procedure Tproducts_edit_form.WmAfterShow(var Msg: TMessage);
begin
self.ActiveControl:= search_txt;
//showmessage(Screen.ActiveControl.Name);
//PostMessage(search_txt.Handle, WM_SETFOCUS, 0, 0);
end;

奇怪的是,如果取消注释 showmessage 和 postmessage,TEdit 会正确获得焦点。如果我不这样做,则表单会打开,但即使 Screen.ActiveControl.Name 告诉我我想要的控件具有焦点,TEdit 也不会获得焦点。

有什么想法吗?

【问题讨论】:

  • 使编辑控件具有TabOrder0,这就是您需要做的所有事情。
  • 我无法让它工作...确保 TEdit 的 TabOrder 属性及其所有父容器都有 TabOrder := 0。
  • 我无法理解该评论。你似乎在自言自语。
  • 编辑控件的 TabOrder = 0,行为仍然相同。
  • 为我工作。你的程序有什么不同。你没有显示程序。只是几块碎片。这确实是调试的关键,而你真正的问题是你还没有学会调试。而不是理解你的问题,你只是一次又一次地攻击,而没有获得正确的理解。因此,请创建minimal reproducible example 来重现该问题。然后我预测您将能够自己解决问题。

标签: delphi focus


【解决方案1】:

使用Form.ActiveControl(不是Screen.ActiveControl)属性来设置控件的焦点是正确的,但是在OnShow中使用它,而不是在OnCreate等中使用它..:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    ActiveControl = Edit1;
}

如果不起作用,可能是因为手动干扰了窗口消息处理程序,消息队列。

【讨论】:

    【解决方案2】:

    windowsmessage 技术正在工作,并且要获得焦点的控件的 TabOrder 确实必须为零。

    我遇到的问题是我的控件停靠在 DevExpress Bar 中。这些栏的工作方式使得无法聚焦停靠在 DevExpress Bar 中的非 DevExpress 控件。

    【讨论】:

    • 问题中没有提到这一点。这就是为什么我们应该进行复制。
    • 从来没有想过这会导致这样的问题......我的经验有限的标志。感谢您的宝贵时间
    • 总是值得孤立一个问题,以便您完全理解它。否则,您将解决通常更糟糕的错误问题。化繁为简!
    猜你喜欢
    • 2015-04-26
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    相关资源
    最近更新 更多