Помощь - Поиск - Пользователи - Календарь
Полная версия: Keypressed в цикле
Форум «Всё о Паскале» > Pascal, Object Pascal > Теоретические вопросы
Soxatyi
Такая проблема. Необходимо вставить паузу в цикл, т.е. если во время выполнения цикла я нажал любую клавишу, то программа останавливается на 2 сек., а потом цикл продолжается. Приведу простой ппример:
program delay_key;
var x:integer;
begin
x:=0;
repeat;
x:=x+1;
writeln(x);
delay(1000);
if keypressed then delay(10000);
until(x=30);
readln;
end.

Здесь такая бага: после одного нажатия клавиши программа дальше всегда вставляет паузу, т.е. сменив значение keypressed на TRUE, она при следующем проходе цикла так и оставляет это значение. Нужно, чтобы от одного нажатия пауза вставлялась один раз. Если я потом опять нажал на кнопку, то пауза опять вставится, и т.д.
По логике, в if..then после длинного delay надо впихнуть что-то вроде keypressed:=FALSE (ибо keypressed суть boolean), но выдается ошибка 122.
Что делать?
volvo
Цитата
По логике, в if..then после длинного delay надо впихнуть что-то вроде keypressed:=FALSE (ибо keypressed суть boolean), но выдается ошибка 122.
Ага, прямо сейчас Паскаль даст тебе присвоить функции логическое значение... KeyPressed это все же функция ...

Цитата
Что делать?
После Delay чистить буфер клавиатуры:
repeat;
x:=x+1;
writeln(x);
delay(1000);
if keypressed then delay(10000);
while keypressed do readkey; { чистим буфер... }
until(x=30);

... и при следующем вызове KeyPressed она проверит буфер, он пуст и KeyPressed вернет значение False...
Soxatyi
Спасибо огромное. )
Romtek
Мне по душе больше такой вариант:
uses crt;

var x: longint;
pause: boolean;
begin
pause := false;
x := 0;
repeat
if not pause then { если не пауза, то что-то делать... }
begin
x:=x+1;
writeln(x);
end;
if keypressed then
begin
pause := not pause; { Переключение состояния паузы (вкл./выкл.) }
while keypressed do readkey; { чистим буфер... }
end;
until(x=$FFFA);
end.

При нажатии на любую клавишу цикл продолжается, но x не увеличивается, пока снова не будет нажата какая-то клавиша.
Преждевременный выход по комбинации Ctrl-C.
Guest
Вариант
while keypressed do readkey;


Невсегда работает кооректно. Лично я напрямую писал адрес начала буфера клавиатуры, в адрес конца, это и быстрее, и буфер точно будет очищен:

memW[$0, $042c] := memW[$0, $042a];



Мог что-то напутать, не могу проверить - Паскаля нет под рукой.
volvo
Guest, приведи пример, КОГДА именно
while keypressed do readkey;
не будет работать корректно, и заодно попробуй свой код скомпилировать, скажем, в Дельфи 6 (как консольное приложение).

По-моему, использование библиотечных функций всегда предпочтительнее использования трюков...
Guest
В Делфи это конечно не прокатит, так как данный метод расчитан чисто для ДОС. Все дело в том, что именно по этим адресам ДОС хранит адрес начала и конца буфера клавиатуры, где их хранит Windows, мне неизвестно. Этот метод не пройдет в Делфи потому, что все приложения в ней компилируются в защищенном режиме (даже консольные), а там уже другая модель памяти и т.д. Аналогично, ты не сможешь записать в Делфи что-то типа:
 xor  ax, ax
int 16h
volvo
Guest, я прекрасно знаю, что это не пойдет в Дельфи (и почему оно там не пойдет - тоже), поэтому и говорю, что не стоит пользоваться тем, что рассчитано на какой-то конкретный компилятор, а вдруг придется перейти на другой? ;)

Так как насчет примера некорректной работы моего метода очистки буфера клавиатуры?
pasman
а мона так:

program delay_key;
var x:integer;
kl:char;
begin
x:=0;
kl:=#0;
repeat;
x:=x+1;
writeln(x);
delay(1000);
if keypressed then kl:=readkey;
if kl<>#0 then delay(10000);
until(x=30);
readln;
end.
Guest
Цитата(volvo @ 11.10.2005 1:58)
GuestТак как насчет примера некорректной работы моего метода очистки буфера клавиатуры?
Прошу прощения, что не мог ответить ранее, был в поездке. Твой вариант некорректен в том случае, когда пользователь нажал и удерживает клавишу, в твоем случае буфер просто не будет успевать очищаться, в моем - да.
volvo
Цитата(Guest @ 15.10.2005 17:38)
Твой вариант некорректен в том случае, когда пользователь нажал и удерживает клавишу, в твоем случае буфер просто не будет успевать очищаться, в моем - да.

Да твой вариант вообще не компилится на многих компиляторах, о какой корректности ты мне говоришь? Ты мне приведи код, который корректно компилится ХОТЯ БЫ под Дельфи + FPC + TP, а потом начинай искать ошибки в чужих программах !!!

Кстати, в случае если юзер нажал и не отпускает кнопку, мой код также отработает. Только что проверил...
Guest
Мой вариант компилится только на 16-ти битных компиляторах,
почему - говорилось выше, странно, что ты опять поднимаешь эту тему.
Простейший вариант, когда твой вариант не сработает
uses
CRT;
var
ch : char;
begin
ClrScr;
WriteLn('Press and hold any key...');
ReadKey;
While KeyPressed do ReadKey;
WriteLn('Bye...');
end.

Если нажать и удерживать клавишу, то программа не должна сразу
завершиться. В моем варианте допущена ошибка (пришлось поставить Pascal для проверки), на
самом деле нужно было писать:
memW[$0: $042c] := memW[$0: $042a]

Применение это нашло здесь: http://www.borlpasc.narod.ru/prog/Soliter.zip
volvo
Цитата(Guest @ 15.10.2005 19:19)
Мой вариант компилится только на 16-ти битных компиляторах, почему - говорилось выше, странно, что ты опять поднимаешь эту тему.
Тему-то, на самом деле, поднимаешь ты. Я могу только еще раз повторить, что для того чтобы избежать БОЛЬШИХ проблем при переходе с 16-ти на 32-х битные компиляторы я бы советовал (и об этом я уже говорил выше) пользоваться ТОЛЬКО библиотечными функциями...

Цитата(Guest @ 15.10.2005 19:19)
Простейший вариант, когда твой вариант  не сработает
:D Смеяться уже можно? Чего это "не сработает"? У меня прекрасно работает...
Причем и в TP70, и в FPC 2.0.0 (кстати, а какой вариант ты мне можешь предложить для FPC? Не писать пока программы?)
Guest
Цитата(volvo @ 15.10.2005 20:56)
:D Смеяться уже можно? Чего это "не сработает"? У меня прекрасно работает...

Смеяться ты можешь, когда хочешь, лишь была причина, а то окружающие не так поймут...
То есть ты хочешь сказать, что программа в моем примере не завершается, пока ты удерживаешь клавишу?
hiv
2Guest: А я тоже смеюсь :D
Если считаешь себя правым - открывай свою школу. Чукча не читатель, чукча - писатель. smile.gif
Guest
Цитата(hiv @ 17.10.2005 9:51)
2Guest: А я тоже смеюсь :D
Если считаешь себя правым - открывай свою школу. Чукча не читатель, чукча - писатель. smile.gif


Без комментариев...
Если есть, что сказать по делу, то говори, а кусаться мы тоже умеем
volvo
Кусаться будешь в другом месте. Тебе уже все сказали, нечего здесь флуд разводить !
Закрыто.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.