Помощь - Поиск - Пользователи - Календарь
Полная версия: Обработка (одновременного) нажатия клавиш
Форум «Всё о Паскале» > Pascal, Object Pascal > Теоретические вопросы
4epenOK
Прошу прощенья, если такая тема уже существует. Искал искал, но не нашёл то, что мне нужно. А нужно мне вот что: Как обрабатывать одновременное нажатие нескольких клавиш (от 2-х и более). Причём нужно, чтобы можно было использовать любые клавиши в связке с любыми, в том числе Ctrl, F1-F-12, Shift, Tab, Caps Lock, Alt... Например Esc + Alt или Ctrl + 'B'. Коды цифр и букв я знаю, а коды Alt, Ctrl и им подобных-нет. Также хочется знать как Паскаль оперирует с событиями Клавиши_нажата, Клавиша_отпущена. Хочется сделать так, чтобы при одновременном нажатии клавиш программа делала одно, при отпускании обоих клавиш- другое.

P.S. Одновременное нажатие не обязательно значит в одно мгновение. Допускается нажатие одной клаваши и не отпуская её, нажатие другой.

Использую Turbo Pascal 7.0
Просветите по этому вопросу Plz
volvo
Цитата
Коды цифр и букв я знаю, а коды Alt, Ctrl и им подобных-нет.
Посмотри здесь: прерывания

Цитата
Также хочется знать как Паскаль оперирует с событиями Клавиши_нажата, Клавиша_отпущена
При нажатии клавиши генерируется ее скан-код, при отпускании - тот же скан-код, увеличенный на 128 ...
4epenOK
На счёт твоей программы... Мне непонятно что это за переменная такая scan и как ты булевской переменной присваиваешь значения не true или false например isCtrl:=(scan=29).
Ищё одно. Объясни пожалуйста какие виды скан кодов есть и для чего они нужны. Например для одной и той же клавиши я встречал разные цифровые и даже цифро-буквенные значения. Что такое DEC и HEX? И для чего служат символы @ $ # в Паскале?
volvo
Цитата
и как ты булевской переменной присваиваешь значения не true или false например isCtrl:=(scan=29).
smile.gif Да что ты? Это как раз будет равно True, если Scan будет равен 29, и False - в любом другом случае... В переменную isCtrl заносится результат сравнения, который есть величина логическая, и следовательно True/False...

Цитата
что это за переменная такая scan
В обработчике прерывания клавиатуры я в эту переменную читаю содержимое $60-го порта, то есть, это и есть скан-код клавиши...

Цитата
Что такое DEC и HEX
DECimal (десятичное) и HEXadecimal (16-ричное)
Цитата
И для чего служат символы @ $ # в Паскале?

@ - взятие адреса
$ - префикс описания 16-ричной константы
# - следом за этим идет 10-ный ASCII-код символа, результат выражения - символ с заданным кодом...

Цитата
какие виды скан кодов есть
А вот с этого места - поподробнее... Я всегда считал, что скан-код - это однозначно определяющее клавишу число, зависящее только от ее расположения на клавиатуре... А что, есть еще какие-то?
4epenOK
Значит DEC это то число, которое мы вводим поле #. Например if readkey=#27 then ...
А почему же я знаю, что код Esc 27, а в этой таблице (да и других подобных) он равен 1 (01)?
http://systemgroup.narod.ru/tema/hardware/scancode.html
http://ntlib.chat.ru/ware/tables/scan.htm
И ещё. Я так и не понял какие коды у клавиш Ctrl, Shift... Видимо нужно почаще информатикой заниматься smile.gif
volvo
Цитата
А почему же я знаю, что код Esc 27, а в этой таблице (да и других подобных) он равен 1 (01)?
Не путай Ascii - код и скан-код... Ascii-код кнопки Escape действительно равен 27, а вот ее скан-код - единица...

Цитата
Я так и не понял какие коды у клавиш Ctrl, Shift...
У Ctrl скан-код = $1D(2910), а у Shift-а их два - у того, что слева - $2A(4910), а у правого - $36(5410)
4epenOK
Спасибо, что разъяснил. А как же тогда работать со скан кодами? Например я ведь не могу написать if readkey=$1D then writeln('Зажат Ctrl');
Можно ли перевести Ascii-код в скан?
И ещё ты сказал
Цитата
при отпускании - тот же скан-код, увеличенный на 128

Это значит что если я отпущу Ctrl то сгенерируется $1D+128 ?
volvo
Цитата
И ещё ты сказал
А еще я сказал, что
Цитата
скан-код - это однозначно определяющее клавишу число, зависящее только от ее расположения на клавиатуре...
, то есть ответ на предыдущий вопрос - нет... Нельзя перевести в общем случае Ascii -> скан-код...

Цитата
Например я ведь не могу написать if readkey=$1D then writeln('Зажат Ctrl');
Нет конечно... Ты вообще не можешь работать со служебными клавишами типа Ctrl/Alt/Shift через ReadKey - только через Scan-codes (для чего тебе понадобится писать обработчик прерывания) или так, как написано здесь:
Asc Ii
TarasBer
Я вот скачал __IV.PAS и что-то она стрелочки неправильно показывает...
Могу предложить свой модуль KEYS.PAS.
Для его использования надо его подключить, в начале программы написать InitKeys, в конце - DoneKeys. И в процессе работы использовать функцию Pressed.
Программа, демонстрирующая работу модуля и одновременно помогающая понять, какой клавише какой код соответствует там же в архиве.
В модуль специально вставлен код, вырубающий программу при нажатии CTRL+C, даже если программа занята другими делами. Типа защита от зависаний. А если требуется, например, чтобы программа при таком выходе закрывала графику, то надо присвоить процедурной переменной HaltProc процедуру, закрывающую графику. Если ничего не присваивать, то при таком вырубании программа просто прерывания на место вернёт и надпись выведет, что типа нажато было CTRL+C.
Ещё модуль не занимается очисткой клавиатурного буфера, поэтому либо он засоряется, либо его очищает сама программа, использующая модуль.
И определить одновременное нажатие трёх буквенных клавиш она не может. По-моему, тут уже дело в конструкции клавиатуры.
volvo
А я вот скачал Keys - так у меня OPOZN.PAS вообще компилироваться отказывается:
Нажмите для просмотра прикрепленного файла

Это так задумано, или что?
TarasBer
Цитата(volvo @ 7.05.2007 15:38) *

А я вот скачал Keys - так у меня OPOZN.PAS вообще компилироваться отказывается:
Нажмите для просмотра прикрепленного файла

Это так задумано, или что?


Не, так не задумано. Это такие настройки компилятора у вас.
У меня из опций синтаксиса (прочие опции тут вроде неважны) включены: (TP7.1) Strict var-strings, Extended Syntax, Open Parameters. Выключены: Complete Boolean Eval и Typed @ Operator
Какая-то из этих опций и запрещает присваивание. А вообще можно обхитрить компилятор.
То есть заменить
HaltProc := AtLast
на
@HaltProc := @AtLast

правда, для этого Typed @ Operator вроде надо вырубить.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.