IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Как задействовать стрелки?
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 9

Репутация: -  0  +


Стал вот потихоньку разбираться с паскалем, вроде что то получается. Вот возникла проблема: как задействовать стрелки и прочии несимвольные клавиши? С буквами-цифирьками вроде все просто, пишешь например C:=readln, а потом разными способами опредиляешь, что надо сделать с этой клавишей. А вот как быть со стрелками - как то непойму. Они вроде таким способом в строковую переменную ничего не записывают. Где-то краем уха услышал, что используется запись каким-то сложным шифром, а вот как его после этого опредилять, и какие кнопки каким шифром опредиляются - не слышал. Может здесь кто подскажет, как это все надо делать?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 930
Пол: Мужской

Репутация: -  11  +


Дык просто. При нажатии курсоров, эфок и т. д. В буфер клавы записывется два числа, впереди стоит 0.
Код

{ПРОСМОТР КОДОВ КЛАВЫ} USES CRT;
VAR Q3:BYTE;
    Q8:WORD;
BEGIN
FOR Q3:=1 TO 100 DO BEGIN Q8:=ORD(READKEY); WRITELN(Q8); DELAY(200);
 END;
END.


Для чтения клавы в проге используй IF KEYPRESSED=TRUE THEN READKEY
Время от времени обнуляй буфер FOR Q:=1 TO 15 DO IF KEYPRESSED=TRUE THEN READKEY

Сообщение отредактировано: SKVOZNJAK -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3





Группа: Пользователи
Сообщений: 9

Репутация: -  0  +


Это я понял, спасибо. А вот как потом этот код обрабатывать?. Влоб "If c=ord(75) then..." (Влево) - не берется. Вроде как то подругому надо, только как?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 930
Пол: Мужской

Репутация: -  11  +


IF KEYPRESSED=TRUE THEN IF ORD(READKEY)=0 THEN IF ORD(READKEY)= ВТОРАЯ ЦИФРА КОДА КЛАВИШИ THEN GOTO 1111
Хотя, вместо гото можно использовать и что-нибудь другое.

IF KEYPRESSED=TRUE THEN CASE ORD(READKEY)
50: .....
100: .........
0: CASE ORD(READKEY)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Раз уж речь пошла про клавиатуру, то позвольте рссказать о еще одном методе (вместо READ, READKEY и прочего) считывания нажатых клавиш
без всеких "If Ord(readkey) =0 then нажата не буква"
1)начиная с адреса 0:$41A до 0:$41C находится буфер клавиатуры
просматривая его можно определять что нажато
2) If Port[$60]<$80 then ...
так нужно опрашивать порт клавы, с целью выяснения нажатой клавиши,
лично я использую всегда его - он очень быстрый и красивый,
не нужно мучаться с кодами клавиш - там используется номер клавиши на клавиатере, и все клавиши пронумерованны!


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 930
Пол: Мужской

Репутация: -  11  +


Но обнулять буфер всё-равно надо! Иначе при запусках, торможениях и ускорениях оно таких глюканов ловить будет!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Да, SKVOZNJAK, согласен с вами, обнуление буфера - это так надо сделать:
mem[0:$41C]:=mem[0:$41A] - т.е. концу буфера приравниваем начало.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8





Группа: Пользователи
Сообщений: 9

Репутация: -  0  +


Oleg_Z
А можно поподробнее про этот метод, я паскалем недавно занялся и можно сказать, что пока еще чайник.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Смотрю...
*****

Группа: Пользователи
Сообщений: 1 055
Пол: Мужской
Реальное имя: Пшеничный Алексей Анатольевич

Репутация: -  6  +


А может проще:

Код

Repeat
  {выполняем программу до нажатия}
Until KeyPressed;
 Ch:=ReadKey;
 If Ch=#0 then
 Begin   {функциональная клавиша}
   Ch:=ReadKey;
   Case Ch of
   ....
   End;
 End
    else
 Begin    {обычная клавиша}
   Case Ch of
   ...
   End;
 End;



--------------------
Если что-то не делает того, что вы запланировали ему делать - это еще не означает, что оно бесполезно.
--------------------
Прежде, чем задать вопрос - Правила :: FAQ :: Поиск
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


APAL, не согласен с вами, так не проще.
ДенисС, этот метод как раз использует функция keypressed (определяет нажата ли клавиша)
Вот тестовая программа, которая позволяет узнать сканкоды всех клавиш:
Код
uses dos;
var

scancod:word;

begin
repeat
 If port[$60]<$80 then
 begin
  scancod:=port[$60];
  mem[0:$41C]:=mem[0:$41A]; {очистка}
  writeln(scancod)
 end
until scancod=1;
end.


а вот эта более продвинутая программа:
Код

uses dos,crt;
var

scancod:word;

begin
clrscr;
repeat
 If port[$60]<$80 then
 begin
  scancod:=port[$60];
  mem[0:$41C]:=mem[0:$41A]; {®зЁбвЄ }
  writeln(scancod);
  port[$60]:=$80;
 end;
If (scancod<>1) and (scancod<>0) then begin port[$60]:=$80; scancod:=0 end;
until scancod=1;
end.

Итак обращаясь к порту $60 мы можем не только определить нажата ли клавиша, но и (что гораздо важнее) определить нажатую клавишу!

в этих программах код клавиш - scancod .
Вот примеры сканкодов:
ESC =1
ENTER=28
SPASE=57
1=2 (клавиша 1 имеет код 2 )
n=n+1(клавиша n имеет код n+1, например 3-код4)
q=16
... (клавиши левее на 1 больше)
p=25 и т.д

--------------------------------
преимущества использования конструкции PORT[$60]
1) выигрыш в скорости:
keypressed использует тоже обращение к портам,
keypressed лежит в модуле CRT ---> компилируется с типом FAR --> задержка на несколько милисекунд, и занимает лишний байт!!!!!!
2) можно использовать не только как keypressed но и как readkey (2 в 1)
3) не надо мучаться с кодировками, все клавиши пронумерованны на всех компах одинаково
------------------------------
какие будут вопросики B)


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Смотрю...
*****

Группа: Пользователи
Сообщений: 1 055
Пол: Мужской
Реальное имя: Пшеничный Алексей Анатольевич

Репутация: -  6  +


А если надо узнать в какой кодировке была нажата клавиша и если важен регистр?
Ведь это дополнительные затруднения!
Конечно они решаются, но это добавочные усложнения. (можно конечно все это офрмить в виде функций)

Я конечно не спорю, в некоторых случаях предпочтительно обращаться прямо к порту, НО также, в некоторых случаях, удобнее использовать ReadKey и KeyPressed.

К примеру - элементарный случай - программист начинающий. smile.gif


--------------------
Если что-то не делает того, что вы запланировали ему делать - это еще не означает, что оно бесполезно.
--------------------
Прежде, чем задать вопрос - Правила :: FAQ :: Поиск
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Да,APAL, согласен тогда разделим сферы интересов:
-------------------
Port[$60] :
1) игры (где надо управлять с клавы чем-либо )
2) резиденты ( в зависимости от цели конечно)
3) вирусы (где надо отключить клаву (хотя на пасе -это редкость))
4) ОС (тут тогда можно свою кодировку придумать)
5) учебные программы (я заметил, что сейчас модно заставлять студентов не пользоваться стандартными средствами)
-----------------
keypressed (и прочие встроенные средства):
ВСЕ ОСТАЛЬНОЕ


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Смотрю...
*****

Группа: Пользователи
Сообщений: 1 055
Пол: Мужской
Реальное имя: Пшеничный Алексей Анатольевич

Репутация: -  6  +


Полностью согласен!

P.S.: У тебя хорошо получается разложить все "по полочкам".
Доходчиво!


--------------------
Если что-то не делает того, что вы запланировали ему делать - это еще не означает, что оно бесполезно.
--------------------
Прежде, чем задать вопрос - Правила :: FAQ :: Поиск
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Я бы ещё порекомендовал использовать модифицированную функцию ReadKey:

Function ReadKey:Word;Assembler;
Asm
XOR AH,AH
INT 16h
OR AL,AL
JZ @@1
XOR AH,AH
@@1:
End;

Отличие от стандартной заключается в том, что эта возвращает расширенный код клавиши. Для клавишь типа '1' или 'y' он ничем не отличается, а для 'F1' или '<-' возращает значение типа $XX00.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Отлично, думаю надо создать тему "Замена стандартных средств"
и скидывать туда все подобные исходники!
APAL, что вы на это скажите? (тем более в разделе задачи, про листинг Assign есть исходники модуля system - можно переделать!)


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


не забывайте также, что седьмой бит значения scancode:=Port[$60] - это флаг нажатия/отпускания клавиши... т.е. если scancode and $80>0, то клавишу отпустили, если 0 - нажали...
также есть некоторые клавиши (Pause, WinKeys, дополнительная цифровая клавиатура - т.н. GreyPad), которые выдают несколько кодов за раз (до четырех) и на нажатие и на отпускание
пример:
Код

var scancode: byte;
     keyup: boolean; {false - нажатие}
     shift: boolean;  {индикатор нажатия клавиши "Shift"}
...
 scancode:=Port[$60];  {последнее событие клавиатуры}
 keyup:=scancode and $80>0; {выцепляем 7-й бит}
 scancode:=scancode and $7F; {убираем 7-й бит}
 if scancode=$2B then shift:=not keyup;  {шифт нажат или отпущен}
...

далее можно проверять флаг shift при обработке обычных клавиш...

но этот код лучше всего использовать в составе обработчика прерывания клавиатуры (как например сделано в моей игрушке "танки", кое-какие исходники которой выложены на форуме). Если же нужна вся клавиатура, а обработчик делать влом (таблицы офигенные набивать), есть еще вариант, небольшая процедурка, потом запишу сюда, если надо
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Смотрю...
*****

Группа: Пользователи
Сообщений: 1 055
Пол: Мужской
Реальное имя: Пшеничный Алексей Анатольевич

Репутация: -  6  +


Цитата(Oleg_Z @ 6.04.04 10:05)
APAL, что вы на это скажите?

Идея хорошая!

Если откапаю в своем архиве выложу модуль для вывода текста через видио память и сохранение области экрана в кэш и может еще что-то найду. Это уже почти CRT... smile.gif

Так можно заменить все в Паскале, но главное чтобы это было оправдано...


--------------------
Если что-то не делает того, что вы запланировали ему делать - это еще не означает, что оно бесполезно.
--------------------
Прежде, чем задать вопрос - Правила :: FAQ :: Поиск
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 930
Пол: Мужской

Репутация: -  11  +


Ну, если уж почувствовали в себе силушку богатырскую, то могу подсказать, где паскаль перепахивать ;) - в доступе к памяти в ПМ до сих пор конь не валялся. Вот потому-то FPC и рулит.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


процедурка для проверки нажатых клавиш - обычных, модификаторов (shift, ctrl, alt) и переключателей (Num Lock, Caps Lock, Scroll Lock). Если нет нажатых клавиш - везде нули... нажатий не ждет...
вариант чисто на Паскале:
Код

uses dos;

procedure ReadKeyExt(var ASCII,Scan,Reg:Byte);
var Regs:Registers;
begin
 Regs.AH:=2; Intr($16,Regs); Reg:=Regs.AL; Scan:=0;
 Regs.AH:=1; Intr($16,Regs); ASCII:=0;
 if Regs.Flags and fZero=0 then begin
   Regs.AH:=0; Intr($16,Regs);
   Scan:=Regs.AH; ASCII:=Regs.AL;
 end;
end;

Reg рассматривать как набор битов - флагов клавиш-модификаторов
Scan - сканкод клавиши (любой)
ASCII - код нажатого символа (в текущей кодировке/состоянии регистров)
если хотите, можете переписать на ассемблере
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


ASCII можно объявить как Char, в ней будет возвращаться то же, что и из обычного Readkey...
procedure ReadKeyExt(var ASCII: char; var Scan, Reg: byte);
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 19.04.2024 16:58
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name