Симфония на клавиатуре(статья)

=== Симфония на клавиатуре(статья) ===
Перевод одноимённой статьи с сайта delphi.about.com )
Начиная с самого рассвета компьютерной промышленности, клавиатура была первичным устройством ввода информации, и вероятнее всего сохранит свою позицию ещё долгое время.
События клавиатуры, наряду с событиями мыши, являются основными элементами взаимодействия пользователя с программой. В данной статье пойдёт речь о трёх событиях, которые позволяют отлавливать нажатия клавиш в приложении Delphi: OnKeyDown, OnKeyUp и OnKeyPress.
Для получения ввода с клавиатуры, приложения Delphi могут использовать два метода. Самый простой способ, это воспользоваться одним из компонентов, автоматически реагирующем на нажатия клавиш, таким как Edit. Второй способ заключается в создании процедур в форме, которые будут обрабатывать нажатия и отпускания клавиш. Эти обработчики могут обрабатывать как нажатия одиночных клавиш, так и комбинаций. 
Итак, вот эти события:
* OnKeyDown - вызывается, когда на клавиатуре нажимается любая клавиша.
* OnKeyUp - вызывается, когда любая клавиша на клавиатуре отпускается.
* OnKeyPress - вызывается, когда нажимается клавиша, отвечающая за определённый ASCII символ.
Теперь самое время посмотреть, как выглядят в программе заголовки обработчиков:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
Все события имеют один общий параметр, обычно называемый Key. Этот параметр используется для передачи кода нажатой клавиши. Параметр Shift (в процедурах OnKeyDown и OnKeyUp), указывает на то, была ли нажата клавиша в сочетании с Shift, Alt, и Ctrl.
==== Фокус ====
Фокус, это способность получать пользовательский ввод через мышь или клавиатуру. Получать события от клавиатуры могут только те объекты, которые имеют фокус. На форме активного приложения в один момент времени может быть активным (иметь фокус) только один компонент.
Некоторые компоненты, такие как TImage, TPaintBox, TPanel и TLabel не могут получать фокус, другими словами, это компоненты, наследованные от TGraphicControl. Так же не могут получать фокус невидимые компоненты, такие как TTimer.
; OnKeyDown, OnKeyUp
: События OnKeyDown и OnKeyUp обеспечивают самый низкий уровень ответа клавиатуры. Обработчики OnKeyDown и OnKeyUp могут реагировать на все клавиши клавиатуры, включая функциональные и комбинации с клавишами Shift, Alt, и Ctrl.
: События клавиатуры - не взаимоисключающие. Когда пользователь нажимает клавишу, то генерируются два события OnKeyDown и OnKeyPress, а когда отпускает, то только одно: OnKeyUp. Если пользователь нажмёт одну из клавиш, которую OnKeyPress не сможет определить, то будет сгенерировано только одно событие OnKeyDown, а при отпускании OnKeyUp.
; OnKeyPress
: OnKeyPress возвращает различные значения ASCII для 'g' и 'G,'. Однако, OnKeyDown и OnKeyUp не делают различия между верхним и нижним регистром.
; Параметры Key и Shift
: Параметр Key можно изменять, чтобы приложение получило другой код нажатой клавиши. Таким образом можно ограничивать набор различных символов, которые пользователь может ввести с клавиатуры. Например разрешить вводить только цифры. Для этого добавьте в обработчик события OnKeyPress следующий код и установите KeyPreview в True (см. ниже).
if Key in ['a'..'z'] + ['A'..'Z'] then Key := #0
Это выражение проверяет, содержит ли параметр Key символы нижнего регистра ('a'..'z') и символы верхнего регистра ('A'..'Z'). Если так, то в параметр заносится значение нуля, чтобы предотвратить ввод в компонент Edit (например).
В Windows определены специальные константы для каждой клавиши. Например, VK_RIGHT соответствует коду клавиши для правой стрелки.
Чтобы получить состояния специальных клавиш, таких как TAB или PageUp можно воспользоваться API функцией GetKeyState. Клавиши состояния могут находиться в трёх состояниях: отпущена, нажата, и включена. Если старший бит равен 1, то клавиша нажата, иначе отпущена. Для проверки этого бита можно воспользоваться API функцией HiWord. Если младший бит равен 1, то клавиша включена. Вот пример получения состояния специальной клавиши:
if HiWord(GetKeyState(vk_PageUp)) <> 0 then
 ShowMessage('PageUp - DOWN')
else
 ShowMessage('PageUp - UP');
В событиях OnKeyDown и OnKeyUp, Key является беззнаковым двухбайтовым (Word) значением, которое представляет виртуальную клавишу Windows. Для получания значения символа можно воспользоваться функцией Chr. В событии OnKeyPress параметр Key является значением Char, которое представляет символ ASCII.
События OnKeyDown и OnKeyUp имеют параметр Shift с типом TShiftState. В Delphi тип TShiftState определён как набор флагов, определяющих состояние Alt, Ctrl, и Shift при нажатии клавиши.
Например, следующий код (из обработчика OnKeyUp) соединяет строку 'Ctrl +' с нажатой клавишей и отображает результат в заголовке формы:
if ssCtrl in Shift then
 Form1.Caption:= 'Ctrl +' + Chr(Key);
Если нажать Ctrl + A, то будут сгенерированы следующие события:
 KeyDown (Ctrl) // ssCtrl
 KeyDown (Ctrl+A) //ssCtrl + 'A'
 KeyPress (A) 
 KeyUp (Ctrl+A)
==== Переадресация событий клавиатуры в форму ====
Клавиатурный обработчик может работать на двух уровнях: на уровне компонентов и на уровне формы. Свойство формы KeyPreview определяет, будут ли клавиатурные события формы вызываться перед клавиатурными событиями компонентов, так как форма может получать все нажатия клавиш, предназначенные для компонента имеющего в данный момент фокус.
Чтобы перехватить нажатия клавиш на уровне формы, до того как они будут переданы компонентам на форме, необходимо установить свойство KeyPreview в True. После этого компонент как и раньше будет получать события, однако сперва они будут попадать в форму, чтобы дать возможность программе разрешить или запретить ввод различных символов.
Допустим, У Вас на форме есть несколько компонентов Edit и процедура Form.OnKeyPress выглядит следующим образом:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if Key in ['0'..'9'] then Key := #0
end;
Если один из компонентов Edit имеет фокус и свойство KeyPreview установлено в False, то этот код не будет выполнен - другими словами, если пользователь нажмёт клавишу '5', то в компоненте Edit, имеющем фокус, появится символ "5".
Однако, если KeyPreview установлено в True, то событие формы OnKeyPress будет выполнено до того, как компонент Edit увидит нажатую клавишу. Поэтому, если пользователь нажмёт клавишу '5', то в Key будет подставлено нулевое значение, предотвращая тем самым попадание числовых символов в Edit.
ПРИЛОЖЕНИЕ: Таблица кодов виртуальных клавиш.
Symbolic 	Value 	Keyboard (or mouse) equivalent
VK_LBUTTON 	01 	Left mouse button
VK_RBUTTON 	02 	Right mouse button
VK_CANCEL 	03 	Control-break processing
VK_MBUTTON 	04 	Middle mouse button (three-button mouse)
VK_BACK 	08 	BACKSPACE key
VK_TAB 	09 	TAB key
VK_CLEAR 	0C 	CLEAR key
VK_RETURN 	0D 	ENTER key
VK_SHIFT 	10 	SHIFT key
VK_CONTROL 	11 	CTRL key
VK_MENU 	12 	ALT key
VK_PAUSE 	13 	PAUSE key
VK_CAPITAL 	14 	CAPS LOCK key
VK_ESCAPE 	1B 	ESC key
VK_SPACE 	20 	SPACEBAR
VK_PRIOR 	21 	PAGE UP key
VK_NEXT 	22 	PAGE DOWN key
VK_END 	23 	END key
VK_HOME 	24 	HOME key
VK_LEFT 	25 	LEFT ARROW key
VK_UP 	26 	UP ARROW key
VK_RIGHT 	27 	RIGHT ARROW key
VK_DOWN 	28 	DOWN ARROW key
VK_SELECT 	29 	SELECT key
VK_PRINT 	2A 	PRINT key
VK_EXECUTE 	2B 	EXECUTE key
VK_SNAPSHOT 	2C 	PRINT SCREEN key
VK_INSERT 	2D 	INS key
VK_DELETE 	2E 	DEL key
VK_HELP 	2F 	HELP key
'0'..'9' 	30..30	0..9 key
'A'..'Z' 	41..5A	A..Z key
VK_NUMPAD0..VK_NUMPAD9	60..69	Numeric keypad 0..9 key
VK_SEPARATOR 	6C 	Separator key
VK_SUBTRACT 	6D 	Subtract key
VK_DECIMAL 	6E 	Decimal key
VK_DIVIDE 	6F 	Divide key
VK_F1..VK_F24 	70..87	F1..F24 key
VK_NUMLOCK 	90 	NUM LOCK key
VK_SCROLL 	91 	SCROLL LOCK key
VK_LSHIFT 	A0 	Left SHIFT key
VK_RSHIFT 	A1 	Right SHIFT key
VK_LCONTROL 	A2 	Left CONTROL key
VK_RCONTROL 	A3 	Right CONTROL key
VK_LMENU 	A4 	Left MENU key
VK_RMENU 	A5 	Right MENU key
VK_PLAY 	FA 	Play key
VK_ZOOM 	FB 	Zoom key
Source: Взято из http://forum.sources.ru
ID: 01509
Category:Статьи