【问题标题】:Why won't my control accept keyboard input?为什么我的控件不接受键盘输入?
【发布时间】:2010-05-12 12:40:37
【问题描述】:

我已经构建了一个自定义控件,我正在尝试向其发送输入。它将接受鼠标输入并正确报告 MouseDown、MouseMove 和 MouseUp,但无论出于何种原因,它都不会接受键盘输入。当我单击它时,它不会获得焦点,并且我按下的任何键都会被任何已经获得焦点的控件解释。

这可能非常简单。我想到的第一个地方是 ControlStyle 属性,但我在帮助文件中唯一能看到的关于键盘输入的是csNoStdEvents,它禁用了它,而我的控件没有。那么我需要做些什么才能使我的控件能够接收输入焦点呢?

【问题讨论】:

  • 你能显示一些代码吗?我在想你可能是从 TControl 继承的,而不是 TCustomControl...(TControl 不是 TWinControl,没有窗口句柄,也无法获取输入焦点 - 想想:TLabel)
  • 它继承自 TCustomControl。

标签: delphi focus custom-controls component-design


【解决方案1】:

有几件事可以尝试:

  • MouseDown,拨打Windows.SetFocus(Handle)。根据我的经验,WinAPI 函数 SetFocus 通常比 VCL 的 SetFocus 方法效果更好。
  • 回复WM_GETDLGCODE消息,回复Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS

【讨论】:

  • 谢谢。要么接受你的,要么接受 Lars 的,因为你们都有将 SetFocus 放入 MouseDown 的答案,而且这很有效。我之所以选择你的,是因为 WM_GETDLGCODE 的东西,我最终也需要它,因为我需要专门捕获箭头键。
  • 仅仅要求DLGC_WANTALLKEYS还不够吗?
  • @Andreas 为什么不呢?我对文档的解释显然是错误的。
  • @David:你得问问微软。我所知道的是DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYSDLGC_WANTALLKEYS 不同。当然,从数学的角度来看(只看数值),这是微不足道的,但操作系统也以不同的方式对待这两个值。所以,不,您需要分别添加选项卡和箭头。例如,请参阅stackoverflow.com/questions/5070573/…
  • @Andreas 谢谢。碰巧我只想要DLGC_WANTARROWS,但我总是想了解我在做什么,即使这样的启蒙只是转瞬即逝!
【解决方案2】:

是否可以像在鼠标按下时调用 SetFocus 一样简单?

procedure TYourCustomControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin
  inherited;

  if CanFocus then
    SetFocus;
end;

【讨论】:

  • 我坚信这是问题所在。
【解决方案3】:

你有WS_TABSTOP 设置吗?我相信,没有它你就没有输入焦点。但这是基于近 10 年前的回忆,当时我正在编写自己的语法高亮代码编辑器,而我早已失去了源代码。

{TWinControl.}TabStop := True; 应该这样做。一个从TWinControl 派生的无操作组件并显示关键事件对话框的快速测试应用程序似乎表明它带来了一切。

【讨论】:

  • 刚刚试了一下,似乎没有任何改变。我仍然无法获得键盘焦点。
【解决方案4】:

我已经检查了我的控件的代码,我看不到任何可能阻止它工作的东西。您是在 Create 过程中调用“继承”吗?

我确实处理过以下事情,但没什么特别的:

procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;

procedure KeyDown(var Key: Word; Shift: TShiftState); override;

【讨论】:

    【解决方案5】:

    击键在表单级别可用吗?也就是 KeyPreview 是否开启,能看到表单的 OnKeypress 事件中的击键吗?您可以在调试器中从那里跟踪它。控件(如 Dan 指出的)是否适合键盘输入?例如,一个 TLabel,虽然它显示文本,但它是一个图形控件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多