Как обнаружить Ctrl+Alt+x в обработчике события нажатия клавиши элемента управления VCL TMemo?

Я создал приложение Delphi VCL с одним элементом управления TMemo, и это код, который у меня есть. Я использую его для обнаружения Ctrl+somekey. Например, когда я нажимаю Ctrl+x, появляется предупреждение ctrl, а эффект Ctrl+x (обрезка) отменяется.

function IsKeyDown(Key: Integer): Boolean;
begin
  Result := (GetAsyncKeyState(Key) and (1 shl 15) > 0);
end;

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
  if IsKeyDown(VK_CONTROL) then
  begin
    ShowMessage('ctrl');
    Key := #0;
  end;

end;

Однако, когда я немного изменил его на это:

function IsKeyDown(Key: Integer): Boolean;
begin
  Result := (GetAsyncKeyState(Key) and (1 shl 15) > 0);
end;

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
  if IsKeyDown(VK_CONTROL) and IsKeyDown(VK_MENU) then
  begin
    ShowMessage('ctrl+alt');
    Key := #0;
  end;

end;

Это больше не работает. Что мне нужно, так это обнаруживать такие комбинации, как Ctrl+Alt+f. Я знаю, что могу использовать TActionList, но я просто хочу знать, почему мой код не работает.

Вместо этого используйте OnKeyDown или OnKeyUp, что дает вам как фактическую нажатую клавишу, так и клавиши-модификаторы (Ctrl, Alt, Shift).

Ken White 23.03.2022 03:11

@KenWhite По моему тестированию, кажется, что в обработчике событий «нажатие клавиши и продолжение» он не может отменить событие клавиши. Это правда?

Fajela Tajkiya 23.03.2022 14:44

Нет это не правда. Вы можете установить Key := 0; для сброса (отмены) ключа в любом случае. Ключ определяется как var Key: Word в определении процедуры.

Ken White 23.03.2022 14:51

Смотрите ответ, который я только что опубликовал. Кроме того, мы не можем получить ваш код откуда-то еще. Вся необходимая информация должна быть здесь, в самом вопросе.

Ken White 23.03.2022 15:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вместо этого вы должны использовать OnKeyDown, который предоставляет вам как значение ключа, так и ключи-модификаторы. В приведенном ниже коде я продемонстрировал, как захватить как одну клавишу-модификатор, так и несколько клавиш-модификаторов.

uses
  { Needed for virtual key codes in recent Delphi versions. }
  System.UITypes;  
                 

procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState);
begin
  if (Key = vkX) and ([ssCtrl] = Shift) then
  begin
    Key := 0;
    ShowMessage('Got Ctrl+X');
  end
  else if (Key = vkZ) and ([ssCtrl, ssAlt] = Shift) then
  begin
    Key := 0;
    ShowMessage('Got Ctrl+Alt+Z');
  end;
end; 

Спасибо за Ваш ответ. Я проверил ваш код и обнаружил, что когда я выбираю текст в TMemo и нажимаю Ctrl+x, я получаю сообщение Got Ctrl+X, но выделение обрезается и исчезает. Кажется, утверждение Key := 0; не действует, верно?

Fajela Tajkiya 23.03.2022 16:03

Это обрабатывается другим сообщением (WM_CUT), потому что это пункт меню в контекстном меню по умолчанию (щелчок правой кнопкой мыши) для элемента управления памяткой. Вам также нужно будет перехватить это сообщение (но это отдельный вопрос, который должен быть в новом посте). К вашему сведению, есть также сообщения WM_COPY и WM_PASTE, которые также используются для комбинаций клавиш Ctrl+C и Ctrl+V.

Ken White 23.03.2022 16:09

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