Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно отлавливать все нажатия клавиш? 
V
    Опции темы
karataev
  Дата 28.1.2006, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 28.1.2006
Где: Россия, Нижний Но вгород

Репутация: нет
Всего: нет



Люди добрые, подскжите пожалуйста, как правильно отловить в Паскале нажатия клавиш, например стрелок и т.п. У меня получается отлавливать только клавиши со значениями таблицы ASCII а всякие там управляющие клавиши не получается... smile
PM MAIL WWW ICQ   Вверх
Snowy
Дата 28.1.2006, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: нет
Всего: 484



Цитата
Описывая свою проблему, не забывайте указывать компилятор и версию.

Если речь идет о TP7, то здесь 3 варианта:
1. Читать данные с порта клавиатуры.
2. Через ассемблерные вставки, используя прерывание клавиатуры.
3. Через чтение области памяти BIOS.
Только вот пример привести не могу - всего не упомнишь, а тут конкретные цифры нужны.
Уж лет 10 на TP не кодил - не помню. Даже прерывание клавы не помню. Вроде $16...
PM MAIL   Вверх
volvo877
Дата 28.1.2006, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



Цитата(karataev @ 28.1.2006, 00:20 Найти цитируемый пост)
как правильно отловить в Паскале нажатия клавиш, например стрелок и т.п.

Стрелки и другие управляющие клавиши - это расширенный код: сначала идет нулевой байт, а потом - собственно код... Программно это выглядит вот так:
Код
ch := readkey;
case ch of
  #0: { расширенный код - какая-то из специальных клавиш }
    case readkey of { берем сам код и обрабатываем: }
      #72: begin { стрелка вверх } end; 
      #80: begin { стрелка вниз   } end; 
      #75: begin { стрелка влево } end; 
      #72: begin { стрелка вправо } end; 
    end;

  #13: { а здесь уже отлавливаешь обычные клавиши - это например был Enter }
  { ... }
end;


Если нужно Ctrl/Shift/Alt/Locks - то там немного по другому: надо смотреть состояние байт по адресу $0:$417 и $0:$418...
Цитата
Байт $0417
Биты
0        Нажат правый Shift
1        Нажат левый Shift
2        Нажат Ctrl
3        Нажат Alt
4        ScrollLock
5        NumLock
6        CapsLock
7        Ins (режим вставки/замещения)

Байт $0418
Биты
0        1, если нажаты Ctrl+Shift (слева)
1        1, если нажаты Alt+Shift (слева)
2        зависит от клавиатуры
3        зависит от клавиатуры
4        1, если нажат ScrollLock
5        1, если нажат NumLock
6        1, если нажат CapsLock
7        1, если нажата клавиша Ins

PM MAIL   Вверх
karataev
Дата 28.1.2006, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 28.1.2006
Где: Россия, Нижний Но вгород

Репутация: нет
Всего: нет



Цитата

Стрелки и другие управляющие клавиши - это расширенный код: сначала идет нулевой байт, а потом - собственно код...

Спасибо большое, с этим я разобрался smile

Цитата

Если нужно Ctrl/Shift/Alt/Locks - то там немного по другому: надо смотреть состояние байт по адресу $0:$417 и $0:$418...

А вот тут не могу объявить переменную, чтобы лежала по этому адресу. Не напомните как это сделать?
PM MAIL WWW ICQ   Вверх
volvo877
Дата 28.1.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



Цитата(karataev @ 28.1.2006, 09:12 Найти цитируемый пост)
А вот тут не могу объявить переменную, чтобы лежала по этому адресу. Не напомните как это сделать?
Используй директиву Absolute:
Код
Var controlByte: byte Absolute $0000:$0417;

PM MAIL   Вверх
Zero
Дата 28.1.2006, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: нет
Всего: 24



Нажатие контрол и остальных клавиш отдельно не фиксируется, а если их нажимать в сочетании, то определить код легко можно так:
С начала напиши такой код:
Код

uses crt;
var
  c:char;
begin
  c:=readkey;
end.

А дальше в отладчике, в пошаговом режиме смотри за изменением, при выполнении строки
Код

c:=readkey;
у тебя будет ожидание нажатия клавиши, и когда ты её нажмёш, в Watches листе воткни переменную с (поставь на неё курсор и нажми CTRL+<F7>, Enter)
Потом в пошаговом режиме посмотри, если нажать одну любую обычную клавишу (например 'q'), то в для неё кодовый символ так и будет 'q' в вочлисте, а если перед этим удерживать клавишу CTRL, а потом нажать 'q', то там будет код #17
Вот пример кода, который выдаст сообщение если нажата комбинация CTRL+<q>:
Код

uses crt;
var
  c:char;
begin
  c:=readkey;
  if c=#17 then write('нажата комбинация клавиш CTRL+<q>');
end.

PM MAIL ICQ   Вверх
volvo877
Дата 28.1.2006, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



Цитата(Zero @ 28.1.2006, 12:18 Найти цитируемый пост)
Нажатие контрол и остальных клавиш отдельно не фиксируется
Уверен? Тогда запусти вот это:
Код

uses crt;
Var
  ct_byte: byte Absolute $0000:$0417;
  s: string;

begin
  repeat
    s := '';
    if (ct_byte and $01) > 0 then s := s + ' R-Shift ';
    if (ct_byte and $02) > 0 then s := s + ' L_Shift ';
    if (ct_byte and $04) > 0 then s := s + ' Ctrl ';
    if (ct_byte and $08) > 0 then s := s + ' Alt ';

    writeln(s);

  until keypressed;
end.

(для выхода - любая обычная клавиша)

PM MAIL   Вверх
karataev
Дата 28.1.2006, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 28.1.2006
Где: Россия, Нижний Но вгород

Репутация: нет
Всего: нет



Цитата

Используй директиву Absolute:

Код

Var controlByte: byte Absolute $0000:$0417;



Я ее и использую, только у меня Free Pascal и он говорит что "Error: absolute can only be associated with a var or const"...
PM MAIL WWW ICQ   Вверх
UpL1nK
Дата 28.1.2006, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 3.12.2005
Где: Тюмень

Репутация: нет
Всего: нет



Цитата(karataev @ 28.1.2006, 14:08 Найти цитируемый пост)

"Error: absolute can only be associated with a var or const"

Может в FP нельзя задавать абсолютный адрес, а только делать наложение на ранее определенную переменную ?

Код

Var t:byte;
      a:integer absolute t;


Это сообщение отредактировал(а) UpL1nK - 28.1.2006, 14:50
--------------------
Макс
PM MAIL ICQ   Вверх
karataev
Дата 28.1.2006, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 28.1.2006
Где: Россия, Нижний Но вгород

Репутация: нет
Всего: нет



Цитата

Может в FP нельзя задавать абсолютный адрес, а только делать наложение на ранее определенную переменную ?


Ну тогда нужно чтобы у переменной t был нужный мне адрес - это какой то замкнутый круг получается... smile
PM MAIL WWW ICQ   Вверх
UpL1nK
Дата 28.1.2006, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 3.12.2005
Где: Тюмень

Репутация: нет
Всего: нет



Просто у меня BPW и абсолютный адрес и наложение работает, хотя я не думаю что есть чтото возможное в BPW , но невозможное в FP smile
--------------------
Макс
PM MAIL ICQ   Вверх
volvo877
Дата 28.1.2006, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



karataev, под какой ОС сидишь? Если под Windows, так пользуйся модулем Windows (какая разница, ты же можешь получить доступ к его функциям и из консольной программы):
Код

uses crt, windows;
Var
  s: string;

begin
  repeat

    s := '';
    if GetKeyState(VK_SHIFT) < 0 then s := s + ' shift ';
    if GetKeyState(VK_CONTROL) < 0 then s := s + ' ctrl ';

    writeln(s);

  until keypressed;
end.

Понажимай Ctrl и Shift, и посмотри как меняется текст...
PM MAIL   Вверх
karataev
Дата 28.1.2006, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 28.1.2006
Где: Россия, Нижний Но вгород

Репутация: нет
Всего: нет



Все, спасибо, я поставил себе Turbo Pascal 7.0 и все заработало. smile
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

1. Обсуждать и делится взломанными компонентами или программным обеспечением

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.1029 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.