Почему мой элемент управления не принимает ввод с клавиатуры?
Я создал пользовательский элемент управления, в который я пытаюсь отправить ввод. Он будет принимать ввод с помощью мыши и правильно сообщать MouseDown, MouseMove и MouseUp, но по любой причине он не будет принимать ввод с клавиатуры. Когда я нажимаю на него, он не получает фокус, и любые клавиши, которые я нажимаю, интерпретируются любым управлением, на котором уже был фокус.
Это, наверное, что-то действительно простое. Первое, что я хотел посмотреть, было в свойстве ControlStyle, но единственное, что я вижу в справочном файле о вводе с клавиатуры, это csNoStdEvents
, что отключает его, и мой контроль не имеет этого. Итак, что мне нужно сделать, чтобы мой контроль мог получить фокус ввода?
5 ответов
Несколько вещей, чтобы попробовать:
- На
MouseDown
, вызовWindows.SetFocus(Handle)
, По моему опыту, функция WinAPISetFocus
часто работает лучше, чем VCLSetFocus
метод. - В ответ на
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
и отображение диалога для ключевых событий, кажется, показывает, что это имеет все значение.
Я проверил код для своего контроля и не вижу ничего, что могло бы остановить эту работу. Вы называете "унаследованным" в процедуре создания?
Я справляюсь со следующим, но ничего особенного:
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 формы? Вы можете следить за этим отладчиком. Подходит ли управление (как указано Даном) для ввода с клавиатуры? Например, TLabel, хотя он отображает текст, является графическим элементом управления.