我已经构建了一个自定义控件,我正在尝试向其发送输入。它将接受鼠标输入并正确报告 MouseDown、MouseMove 和 MouseUp,但无论出于何种原因,它都不会接受键盘输入。当我单击它时,它不会获得焦点,并且我按下的任何键都会被任何已经拥有焦点的控件解释。
这可能是非常简单的事情。我想看的第一个地方是 ControlStyle 属性,但我在帮助文件中唯一能看到的关于键盘输入的是csNoStdEvents
,它禁用了它,而我的控件没有。那么我需要做什么才能使我的控件可以接收输入焦点?
我已经构建了一个自定义控件,我正在尝试向其发送输入。它将接受鼠标输入并正确报告 MouseDown、MouseMove 和 MouseUp,但无论出于何种原因,它都不会接受键盘输入。当我单击它时,它不会获得焦点,并且我按下的任何键都会被任何已经拥有焦点的控件解释。
这可能是非常简单的事情。我想看的第一个地方是 ControlStyle 属性,但我在帮助文件中唯一能看到的关于键盘输入的是csNoStdEvents
,它禁用了它,而我的控件没有。那么我需要做什么才能使我的控件可以接收输入焦点?
有几件事要尝试:
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
;是否可以像在鼠标按下时调用 SetFocus 一样简单?
procedure TYourCustomControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin
inherited;
if CanFocus then
SetFocus;
end;
你有WS_TABSTOP
定吗?我相信,没有它你就没有输入焦点。但这是基于近 10 年前的回忆,当时我正在编写自己的语法高亮代码编辑器,而我早已失去了源代码。
{TWinControl.}TabStop := True;
应该做的。一个快速测试应用程序,它的无操作组件源自TWinControl
关键事件并显示一个对话框,似乎表明它产生了很大的不同。
我已经检查了我的控件的代码,我看不到任何可能阻止它工作的东西。您是否在 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;
击键在表单级别可用吗?也就是 KeyPreview 是否开启,在窗体的 OnKeypress 事件中能看到击键吗?您可以在调试器中从那里跟踪它。控件(如 Dan 指出的)是否适合键盘输入?例如,一个 TLabel,虽然它显示文本,但它是一个图形控件。