2015-11-14 4 views
0

В C#, это было написано так:Как захватить событие комбинации клавиш?

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Control && e.Shift && e.KeyCode == Keys.P) 
    { 
     MessageBox.Show("Hello"); 
    } 
} 

Capturing Ctrl + Shift + P key stroke in a C# Windows Forms application [duplicate]

Я пытался подражать путь они написали это в C# в Delphi X Е8, но это не делает как представляется, работает:

procedure TForm12.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 
begin 
    if (GetKeyState(VK_CONTROL) < 0) and (Key = 53) then 
    ShowMessage('You pressed "ctrl + s"'); 
end; 

Примечание: TForm.KeyPreview Troperty установлен в истинной

Как я могу захватить, что сочетание клавиш событие?

ответ

2

Ключ, который вы ищете, S, имеет код $53. Указанный вами ключ имеет код 53 и является номером . Разница заключается в $, которая обозначает шестнадцатеричный.

Вы бы избежать таких глупых ошибок, и сделать код более ясным, если вы позволяете компилятору сделать работу:

Key = ord('S') 

Вы действительно не хотите использовать магические константы в программе. Это очень важно.

Обратите внимание, что Key является virtual key code и конвенции является то, что для 26 ключей латинского алфавита, они представлены порядковым значением прописной буквы.

сообщение уже проходит состояние клавиш-модификаторов в Shift аргумента, поэтому идиоматичен написать тест следующим образом:

if (ssCtrl in Shift) and (Key = ord('S')) then 

Ваш тест с использованием GetKeyState работает хорошо, но это просто не идиоматическое ,

Обратите внимание, что этот тест, который соответствует этому вопросу, игнорирует состояние других ключей-модификаторов. Действительно, код C# в вопросе также игнорирует состояние модификатора ALT.

Таким образом, вы можете истинный тест на CTRL + S Вы должны также проверить, что другие модификаторы вверх:

if ([ssCtrl] = Shift*[ssCtrl, ssShift, ssAlt]) and (Key = ord('S')) then 

Все это говорит, что, как правило, гораздо легче управлять ярлыки с помощью действия. Это позволит вам напрямую указывать ярлыки и позволить инфраструктуре обнаруживать ключевые события низкого уровня, составляющие ярлык. Дополнительные действия позволяют централизовать обработку действий за кнопками и меню без повторения.

+0

Сэр Дэвид Хеффернан, вы такая легенда. Спасибо за очень сжатый ответ. – Wennie

+0

@David - Я удивлен, что вы сказали бы: «GetKeyState() работает хорошо». Использование ** GetKeyState() ** потенциально ненадежно, поскольку состояние ключа может отличаться во время обработки события, чем оно было во время самого входного события (именно поэтому состояние во время события предоставляется * с * событием). – Deltics

+0

@Deltics Не так. Вы думаете о 'GetAsyncKeyState'. Из документов: * Приложение вызывает GetKeyState в ответ на сообщение с клавиатурой. Эта функция извлекает состояние ключа при генерации входного сообщения. * –

1

Вы можете использовать действия для автоматизации ярлыков. Снимите TActionManager и добавьте TAction. В этом случае назначьте Name, Caption и обработчик события OnExecute, а самое главное - значение для ShortCut. Это может быть строка, представляющая нажатия клавиш, в вашем случае Ctrl+Shift+P. Затем вы можете назначить это действие различным элементам управления или называть его как MyAction.Execute.

+0

Через час я понял, что использование TActionManager очень эффективно, чем моя предыдущая идея. Благодарю. – Wennie

1

В Delphi вы используете Shift: TShiftState, чтобы проверить, какие клавиши «shift» нажаты.

Как указано в комментариях ваша ошибка в том, что ключевое значение для письма s не десятичную 53, но шестнадцатеричное 53, IOW $53 в синтаксисе Delphi.

Я первый думал, что вы также хотели, чтобы проверить ключ shift как в ссылочной источник вашего вдохновения, в этом случае вы можете проверить на эксклюзивной комбинации следующим образом:

procedure TForm15.FormKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if (Key = $53) and ([ssCtrl, ssShift] = Shift) then 
    begin 
    ShowMessage('You pressed "ctrl + shift + s"'); 
    Key := 0; // optional 
    end; 
end; 

Вы можете или может не хотеть очистить параметр Key, чтобы предотвратить дальнейшие действия с помощью фокуса.

Перечитывая свой вопрос после того, как другой комментарий, вы, кажется, хотят, чтобы обнаружить только Ctrl + s комбинацию, в этом случае условие тест эксклюзив становится

if (Key = $53) and ([ssCtrl] = Shift) then 

Я recommed быть точным (эксклюзив) в смену потому что состояние сдвига включает в себя не только клавиши Shift, Ctrl и Alt, но также кнопки мыши и некоторые жесты.

documentation на TShiftState предоставляет другие возможные значения Shift для проверки.

Наконец, как @David Heffernan указывает в своем ответе вместо магической константы ($53) для теста ключа, используйте Ord('S').

+0

Проблема не была связана с состоянием переключения. 'GetKeyState (VK_CONTROL) <0' отлично работает, хотя и не является идиоматическим. Проблема была '53' вместо' ord ('S') = $ 53'. –

+0

@David Спасибо за комментарий. Да, я это видел, но забыл конкретно упомянуть об этом. –

+0

Код не предназначен для проверки клавиши переключения. 'ShowMessage ('Вы нажали' ctrl + s" '); 'Ассер пытается обнаружить Ctrl + S. –

Смежные вопросы