- •Лекція №14
- •Тема 4. Розробка графічного інтерфейсу користувача (продовження) Обробка подій миші і клавіатури План
- •2. Розпізнавання джерела події, натиснутих кнопок і клавіш, координат курсору
- •3. Події клавіатури
- •4. Перетягування даних між об’єктами
- •5. Перетягування і вбудовування об'єктів — Drag&Doc. Плаваючі вікна
- •6. Буксування компонентів у вікні програми
3. Події клавіатури
У віконних компонентах С++Builder визначені три події, пов'язані з клавіатурою. Це події:
OnKeyDown - подія наступає при натисненні користувачем будь-якої клавіші. Можна розпізнати натиснуті клавіші, включаючи функціональні, і кнопки миші, але не можна розпізнати символ натиснутої клавіші.
OnKeyPress - подія наступає при натисненні користувачем клавіши символу. Можна розпізнати тільки натиснуту клавішу символу, розрізнити символ у верхньому і нижньому регістрі, розрізнити символи кирилиці і латинські, але не можна розпізнати функціональні клавіші і кнопки.
OnKeyUp - подія наступає при відпусканні користувачем будь-якої клавіші. Можна розпізнати натиснуті клавіші, включаючи функціональні, і кнопки миші, але не можна розпізнати символ клавіші, що відпускається.
Крім того, при натисненні користувачем клавіші табуляції фокус може перемикатися з елементу на елемент, що викликає події OnEnter і OnExit.
Слід зазначити, що подія OnKeyPress свідомо наступає, якщо натискається тільки клавіша символу або клавіша символу при натиснутій клавіші Shift. Якщо ж клавіша символу натискається одночасно з якоюсь із додаткових клавіш, то подія OnKeyPress може не наступити (відбудуться тільки події OnKeyDown при натисненні і OnKeyUp при відпуску) або, якщо і наступить, то вкаже на невірний символ. Наприклад, при натиснутій клавіші Alt подія OnKeyPress при натисненні символьної клавіші не наступає. А при натиснутій клавіші Ctrl подія OnKeyPress при натисненні символьної клавіші наступає, але символ не розпізнається.
Заголовок обробника події OnKeyDown може мати, наступний вигляд:
void __fastcall TForml::Edit1KeyDown (TObject *Sender,
WORD &Key, TShiftState Shift)
В обробнику події OnKeyDown множина можливих елементів параметра Shift скорочена до ssShift (натиснута клавіша Shift), ssAlt (натиснута клавіша Alt) і ssCtrl (натиснута клавіша Ctrl). Інформація про натиснуті кнопки миші відсутня.
Основний параметр, якого не було раніше - це параметр Key. Зверніть увагу, що він передається по посиланню, тобто може змінюватися в обробнику події. Крім того, зверніть увагу, що це ціле число, а не символ. Параметр Key визначає натиснуту у момент події клавішу клавіатури. Для не алфавітно - цифрових клавіш використовуються віртуальні коди API Windows. Нижче, приведені декілька значень, відповідних найбільш поширеним клавішам.
Клавіша |
Десяткове число |
Шістнадцятиркове число |
Символічнеім'я |
F1 |
112 |
0x70 |
VK_F1 |
Enter |
13 |
0x0D |
VK_RETURN |
Shift |
16 |
0x10 |
VK_SHIFT |
Ctrl |
17 |
0x11 |
VK_CONTROL |
Ait |
18 |
0x12 |
VK_MENU |
Esc |
27 |
0x1В |
VK_ESCAPE |
0) |
48 |
0x30 |
|
1! |
49 |
0x31 |
|
n, N, t, T |
78 |
0x4E |
|
y,Y, h, H |
89 |
0x59 |
|
Параметр Key є цілим числом, що визначає клавішу, а не символ. Наприклад, один і той же код відповідає прописному і рядковому символам "Y" і "у". Якщо, як це звичайно буває, в російській клавіатурі цій клавіші відповідають символи кирилиці "Н" і "н", то їх код буде тим же самим. Розрізнити прописні і рядкові символи або символи латинські і кирилицю неможливо.
Перевіряти натиснуту клавішу можна, порівнюючи Key з цілим десятковим кодом клавіші. Наприклад, реакцію на натиснення користувачем клавіші Enter можна оформити оператором:
if (Key == 13) … ;
Можна порівнювати Key із шістнадцятковим еквівалентом коду. Наприклад, приведеного вище оператора можна записати у вигляді:
if (Key == 0x0D)…;
Для клавіш, яким не відповідають символи, також відповідають іменовані константи, які полегшують написання програми, оскільки не вимагають пам'ятати числові коди клавіш. Наприклад, приведений вище оператор можна записати у вигляді:
іf (Key == VK_RETURN) … ;
Тепер перейдемо до розгляду події OnKeyPress. Заголовок обробника цієї події має вигляд:
void __fastcall TForm1::EditlKeyPress(TObject *Sender, char &Key)
У цей обробник, як і в описані вище, передається параметр Key, що визначає натиснуту клавішу символу. Але тип цього параметра не ціле число, як в попередніх випадках, а char — символ. В даному випадку в обробник передається не віртуальний код клавіші, а символ, по якому можна визначити, прописна це буква, або рядкова, російська, або латинська. Тому описаних вище складнощів з розпізнаванням символів не виникає.
Хай, наприклад, ви поставили користувачу питання, на яке він повинен відповісти символами "Д" або "д" (так), або символами "Н" або "н" (ні). Тоді розпізнати позитивну відповідь в обробнику події OnKeyPress можна оператором:
if ((kеу == 'Д') || (Key == 'д'))… ;
Приведений оператор реагує тільки на позитивну відповідь користувача, не реагуючи на негативну або помилкову відповідь. Реакцію на всі можливі відповіді забезпечує структура множинного вибору switch:
switch (Key)
{
case 'Д': …;
case 'д': …;
break;
case 'Н': …;
case 'н': …;
break;
default: Beep();
}
Тут передбачена реакція на позитивну і негативну відповідь, а також звуковий сигнал при помилковій відповіді.
Подивившись на приведений раніше заголовок обробника, ви можете побачити, що параметр Key передається по посиланню. Це дозволяє в обробнику змінювати Key, змінюючи відповідно його стандартну обробку в компоненті, оскільки ваш обробник події спрацьовує раніше стандартного обробника компоненту. Хай, наприклад, ви хочете мати на формі вікно редагування Edit1, в якому користувач повинен вводити тільки цілі числа без знаку. Ви можете забезпечити безпомилкове введення, підміняючи всі неприпустимі символи нульовим за допомогою, наприклад, наступного коду:
Set < char, ' 0', ' 9'> Dig;
Dig <<'0'<<'1'<<'2'<<'3'<<'4'<<'5'<<'6'<<'7'<<'8'<<' 9';
if (! Dig.Contains(Key))
{ Key = 0;
Beep ( );
}
При натисненні користувачем будь - якої клавіші, окрім клавіш з цифрами, символи підміняються нульовим символом і просто не з'являються у вікні редагування, як ви можете переконатися, зробивши застосування з цим простим прикладом. Функція Beep відтворює при натисненні користувачем помилкової клавіші звуковий сигнал.