Почему мой элемент управления не принимает ввод с клавиатуры?

Я создал пользовательский элемент управления, в который я пытаюсь отправить ввод. Он будет принимать ввод с помощью мыши и правильно сообщать MouseDown, MouseMove и MouseUp, но по любой причине он не будет принимать ввод с клавиатуры. Когда я нажимаю на него, он не получает фокус, и любые клавиши, которые я нажимаю, интерпретируются любым управлением, на котором уже был фокус.

Это, наверное, что-то действительно простое. Первое, что я хотел посмотреть, было в свойстве ControlStyle, но единственное, что я вижу в справочном файле о вводе с клавиатуры, это csNoStdEvents, что отключает его, и мой контроль не имеет этого. Итак, что мне нужно сделать, чтобы мой контроль мог получить фокус ввода?

5 ответов

Решение

Несколько вещей, чтобы попробовать:

  • На 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 и отображение диалога для ключевых событий, кажется, показывает, что это имеет все значение.

Я проверил код для своего контроля и не вижу ничего, что могло бы остановить эту работу. Вы называете "унаследованным" в процедуре создания?

Я справляюсь со следующим, но ничего особенного:

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, хотя он отображает текст, является графическим элементом управления.

Другие вопросы по тегам