powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / OnKeyDown
4 сообщений из 4, страница 1 из 1
OnKeyDown
    #40055385
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если у формы есть процедура, реагирующая на сообщение WM_KEYDOWN, то событие OnKeyDown не выполняется. Почему?

Нужно добавить ключевое слово "inherited" в обработчик WM_KEYDOWN, но почему? Я не наследую форму от формы с переопределением OnKeyDown.

Если есть Action с сочетанием клавиш, то на это сочетание клавиш не сработает ни WM_KEYDOWN, ни OnKeyDown.

Если на форме есть компонент, получающий фокус, то до формы сообщения WM_KEYDOWN не доходят, и убрать фокус нельзя.

Как сделать?
...
Рейтинг: 0 / 0
OnKeyDown
    #40055394
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered
Если у формы есть процедура, реагирующая на сообщение WM_KEYDOWN, то событие OnKeyDown не выполняется. Почему?

Зависит от того, что делается при обработке WM_KEYDOWN.
И inherited в этом обработчике нужен для того, что бы срабатывал OnKeyDown.
В данном случае inherited к наследованию форм отношения не имеет.
...
Рейтинг: 0 / 0
OnKeyDown
    #40055428
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered
Если у формы есть процедура, реагирующая на сообщение WM_KEYDOWN, то событие OnKeyDown не выполняется. Почему?

Сделайте обработчик wm_keydown, состоящий из слова inherited, поставьте на него брейкпоинт, убедитесь в установленной опции use debug dcu, пройдите код отладчиком и разберитесь.

registered
Нужно добавить ключевое слово "inherited" в обработчик WM_KEYDOWN, но почему?

Директива message - частный случай директивы dynamic.

registered
Если есть Action с сочетанием клавиш, то на это сочетание клавиш не сработает ни WM_KEYDOWN, ни OnKeyDown.

И это разумно.

registered
Если на форме есть компонент, получающий фокус, то до формы сообщения WM_KEYDOWN не доходят

Можно установить свойство KeyPreview.
...
Рейтинг: 0 / 0
OnKeyDown
    #40055493
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered
Если у формы есть процедура, реагирующая на сообщение WM_KEYDOWN, то событие OnKeyDown не выполняется. Почему?

Нужно добавить ключевое слово "inherited" в обработчик WM_KEYDOWN, но почему? Я не наследую форму от формы с переопределением OnKeyDown.


Когда кто-то нажал на клавишу, система (Windows) посылает приложению сообщение WM_KEYDOWN. Цикл обработки сообщений приложения выбирает это сообщение из очереди сообщений, когда до него дойдет очередь и отправляет соответствующему окну, в данном случае - форме. В процедурах обрабатывающих это соообщение вызывается обработчик события OnKeyDown. Можете посмотреть код класса TWinControl.
Ваша форма - наследник класса TForm, он в свою очередь унаследован от TWinControl. (TWinControl->TScrollingWinControl->TCustomForm->TForm). Если вы создали обработчик сообщения WM_KEYDOWN и не добавили там inherited, то выполнится ваш обработчик и на этом обработка сообщения закончится. Если вы добавите inherited, то после вашего кода будет вызвана процедура в иерархии предков, которая обрабатывает это сообщение.

Код: pascal
1.
2.
3.
4.
5.
procedure TWinControl.WMKeyDown(var Message: TWMKeyDown);
begin
  if not DoKeyDown(Message) then inherited;
  UpdateUIState(Message.CharCode);
end;



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
function TWinControl.DoKeyDown(var Message: TWMKey): Boolean;
var
  ShiftState: TShiftState;
  Form, FormParent: TCustomForm;
  LCharCode: Word;
begin
  Result := True;
  { First give the immediate parent form a try at the Message }
  Form := GetParentForm(Self, False);
  if (Form <> nil) and (Form <> Self) then
  begin
    if Form.KeyPreview and TWinControl(Form).DoKeyDown(Message) then
      Exit;
    { If that didn't work, see if that Form has a parent (ie: it is docked) }
    if Form.Parent <> nil then
    begin
      FormParent := GetParentForm(Form);
      if (FormParent <> nil) and (FormParent <> Form) and
      FormParent.KeyPreview and TWinControl(FormParent).DoKeyDown(Message) then
        Exit;
    end;
  end;
  with Message do
  begin
    ShiftState := KeyDataToShiftState(KeyData);
    if not (csNoStdEvents in ControlStyle) then
    begin
      LCharCode := CharCode;
      KeyDown(LCharCode, ShiftState); //<---------------------------------
      CharCode := LCharCode;
      if LCharCode = 0 then Exit;
    end;
  end;
  Result := False;
end;



Код: pascal
1.
2.
3.
4.
procedure TWinControl.KeyDown(var Key: Word; Shift: TShiftState);
begin
  if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
end;


Как видно, вызовется обработчик OnKeyDown формы.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / OnKeyDown
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]