Форум программистов, компьютерный форум, киберфорум
Free Pascal
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
1 / 1 / 0
Регистрация: 18.10.2014
Сообщений: 5
1

Программа не реагирует на нажатие клавиш

30.12.2015, 21:50. Просмотров 1452. Ответов 9
Метки нет (Все метки)

Ситуация в том что программа не реагирует на нажатие клавиш, за исключением определенных случаев.

1) если не вызывать ф-цию stPop (либо дважды вызывать перед ней stPush)
2) если превратить ф-ции stPop и stPush в процедуры (вырезав только result:=)
3) если подключить модуль crt, и использовать родной readkey из стандартной библиотеки crt

Собственно вопрос в том, в чём может быть дело (и есть ли грубые ошибки)? Понимаю, что моя ф-ция readkey "кривая", но если дело в ней то почему программа корректно работает в первых двух случаях ?
fpc 2.6.4

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{$MODE OBJFPC}
program main;
//uses crt;
uses keyboard;
 
type
  PList = ^TList;
 
  TList = record
    Data: byte;
    prev: PList;
    Next: PList;
  end; 
 
var
  c:char;
    dat:byte;
  st:Plist;
 
function readkey(iswait: boolean = False): char;
var
  key: tkeyevent;
begin
  if iswait = True then
    Key := PollKeyEvent;
  if key <> 0 then
  begin
    Key := GetKeyEvent;
    Key := TranslateKeyEvent(Key);
  end;
  Result := GetKeyEventChar(Key);
end; 
 
function stEmpty(aList: Plist): boolean;
begin
  Result := (aList = nil);
end;   
 
function stPush(var aList: PList; aData: byte): PList;
var
  p: PList;
begin
  new(p);
  p^.Data := aData;
  p^.prev := aList;
  alist := p;
  Result := p;
end;
 
function stPop(var aList: PList; var aData: byte): PList;
var
  p: PList;
begin
  Result := nil;
  if stEmpty(aList) then
    exit;
 
  p := alist;
  alist := alist^.prev;
  Result := p^.prev;
  dispose(p);
 
end;
 
                    
 
begin
initkeyboard;
stPop(st,dat);
 
repeat
c:=readkey;
//------
until c=#27; 
 
 
 
end.
Добавлено через 18 часов 55 минут
Конечно можно обойти эту проблему, воспользовавшись любым из трех вышеперечисленных вариантов. Но меня больше волнует не решение, меня вгоняет в ступор такое странное и "не логичное" поведение программы.(особенно второй пункт, с банальной заменой ф-ций на процедуры).
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.12.2015, 21:50
Ответы с готовыми решениями:

Почему клавиатура не реагирует на нажатие клавиш с м р у к
Всем привет у меня есть такой вопрос: почему клавиатура не реагирует на нажатие клавиш с м р у к но...

Input не реагирует на нажатие клавиш + и - на Num Lock
В инспекторе Unity добавил свой Axes. Прописал позитивное значение &quot;+&quot; и негативное &quot;-&quot;. В коде...

подскажите - консольное меню не реагирует на нажатие клавиш (case)
вот код, mv 2008 компилируется без ошибок, но при выборе 1, 2, 3 или 4 в меню ничего происходит...

Клавиатура Corsair K65 RGB перестала светиться и не реагирует на нажатие клавиш
Клавиатура Corsair K65 RGB перестала светиться и не реагирует на нажатие клавиш (USB разъем...

9
Модератор
Эксперт по электронике
7355 / 3581 / 1414
Регистрация: 01.02.2015
Сообщений: 11,187
Записей в блоге: 1
30.12.2015, 22:38 2
А сформулируйте задачу. Просто, я вижу непривычное использование структур двунаправленных списков (push/pop возвращают не byte, а указатель на кусок памяти). Причём поле Next полностью забыто. И нет примера использования.
1
1 / 1 / 0
Регистрация: 18.10.2014
Сообщений: 5
30.12.2015, 22:57  [ТС] 3
Ну задачи как таковой нету, делаю просто для себя, изучаю указатели и динам. структуры. поле Next оставил на "потом" - для двусвязных списков (это ведь в принципе не должно никак повлиять на результат ?).

Просто, я вижу непривычное использование структур двунаправленных списков (push/pop возвращают не byte, а указатель на кусок памяти).
Писал иногда заглядывая сюда Паскаль. Программирование на языке высокого уровня: Учебник для вузов, отсюда и ф-ции с возвратом указателя.

Кликните здесь для просмотра всего текста

вот например пример кода из этой книжки, в принципе там это сплошь и рядом, поэтому посчитал что это в порядке вещей =)

Pascal
1
2
3
4
5
6
type pnode = ^node;
     node = record                                
         d : word;
         s : string;
         p : pnode;
     end;

Pascal
1
2
3
4
5
6
7
function push(top : pnode; d : word; const s : string) : pnode;
var p : pnode;
begin
    new(p);
    p^.d := d; p^.s := s;  p^.p := top;
    push := p;
end;


Но стоит stPop и stPush объявить и вызвать не как ф-ции, а как процедуры - то всё ок. Не могу понять из за чего так происходит.
0
Модератор
Эксперт по электронике
7355 / 3581 / 1414
Регистрация: 01.02.2015
Сообщений: 11,187
Записей в блоге: 1
30.12.2015, 23:01 4
А пример использования?
1
1 / 1 / 0
Регистрация: 18.10.2014
Сообщений: 5
30.12.2015, 23:15  [ТС] 5
А пример использования?
В смысле задача ? ну я выше постом написал что как таковой её нету.)

Или пример использования из книги ?
Код оттуда (предыдущий пост) только для того, что бы указать что там используются ф-ции с возвратом указателя.
Вопросов по пример с книги нету. Там ничего интересного нету, всё работает.
Кликните здесь для просмотра всего текста

На всякий случай полный код оттуда если интересно

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
program stack;
const n = 5;
type pnode = ^node;
     node = record                                { элемент стека }
         d : word;
         s : string;
         p : pnode;
     end;
var  top : pnode;                    { указатель на вершину стека }
     i   : word;
     s   : string;
const text : array [1 .. n] of string = ('one', 'two', 'three', 'four', 'five');
{ ------------------------------ занесение в стек --------------------------- }
function push(top : pnode; d : word; const s : string) : pnode;
var p : pnode;
begin
    new(p);
    p^.d := d; p^.s := s;  p^.p := top;
    push := p;
end;
{ ------------------------------ выборка из стека --------------------------- }
function pop(top : pnode; var d : word; var s : string) : pnode;
var p : pnode;
begin
    d := top^.d; s := top^.s;
    pop := top^.p;
    dispose(top);
end;
{ ------------------------------- главная программа ----------------------------- }
begin
    top := nil;
    for i := 1 to n do top := push(top, i, text[i]);        { занесение в стек: }
    while top <> nil do begin                               { выборка из стека: }
        top := pop(top, i, s);     writeln(i:2, s);
    end;
end.


Или я занимаюсь мазохизмом и придумываю себе лишние проблемы ?)
0
Модератор
Эксперт по электронике
7355 / 3581 / 1414
Регистрация: 01.02.2015
Сообщений: 11,187
Записей в блоге: 1
30.12.2015, 23:18 6
В посте №1 тело основной программы
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
begin
initkeyboard;
stPop(st,dat);
 
repeat
c:=readkey;
//------
until c=#27; 
 
 
 
end.
В остальных постах - коды того, что вас не интересует.

Соберите тестовую программу с вашей реализацией стека, которая воспроизводит ошибку.
1
1 / 1 / 0
Регистрация: 18.10.2014
Сообщений: 5
30.12.2015, 23:32  [ТС] 7
Извиняюсь, забыл сразу уточнить в первом посте - при нажатии на Esc не происходит выхода ( readkey ничего не возвращает ). То есть код в первом посте уже воспроизводит ошибку.
Потому и не привел полный код программы.
0
Модератор
Эксперт по электронике
7355 / 3581 / 1414
Регистрация: 01.02.2015
Сообщений: 11,187
Записей в блоге: 1
31.12.2015, 00:06 8
Лучший ответ Сообщение было отмечено kkrk как решение

Решение

Там ошибка - нет инициализации Key в начале выполнения функции. И при IsWait=false значение Key - случайный мусор из стека.

Добавлено через 42 секунды
Минимальная программа работает
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{$MODE OBJFPC}
program main;
 
uses
  KeyBoard;
 
  function ReadKey(IsWait: boolean = False): char;
  var
    Key: TKeyevent;
  begin
    Key := GetKeyEvent;
    Key := TranslateKeyEvent(Key);
    Result := GetKeyEventChar(Key);
  end;
 
var
  c: char;
begin
  InitKeyBoard;
  repeat
  until ReadKey = #27;
end.
Добавлено через 9 минут
Или, другое поведение
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{$MODE OBJFPC}
program main;
 
uses
  KeyBoard;
 
  function ReadKey(IsWait: boolean = False): char;
  var
    Key: TKeyevent;
  begin
    if IsWait then
      Key := GetKeyEvent
    else
      Key := PollKeyEvent;
    Key := TranslateKeyEvent(Key);
    Result := GetKeyEventChar(Key);
  end;
 
var
  c: char;
begin
  InitKeyBoard;
  repeat
    Write('#');
  until ReadKey = #27;
end.
Добавлено через 3 минуты
В примерах в конце ещё добавляют строку DoneKeyBoard;
1
1 / 1 / 0
Регистрация: 18.10.2014
Сообщений: 5
31.12.2015, 00:28  [ТС] 9
В примерах в конце ещё добавляют строку DoneKeyBoard;
Посчитал что нет смысла делать это в тестовой программе, можно и сразу завершиться без этого. Но согласен с тем что так делать не нужно.


Понимаю, что моя ф-ция readkey "кривая", но если дело в ней то почему программа корректно работает в первых двух случаях ?
Изначально и грешил на неё (не инициализированное значение key при значении iswait по умолчанию), но не думал что такая ошибка может дать такие противоречивые результаты, поэтому даже и не стал исправлять её. Никак не ожидал что мусор из стека одной подпрограммы может влиять на то как объявлены другие подпрограммы: как ф-ции или как процедуры. Ну или на то, сколько раз вызывается определенная подпрограмма
Но стоит stPop и stPush объявить и вызвать не как ф-ции, а как процедуры - то всё ок. Не могу понять из за чего так происходит.
если не вызывать ф-цию stPop (либо дважды вызывать перед ней stPush)

Спасибо, теперь всё стало на свои места)
1
Модератор
Эксперт по электронике
7355 / 3581 / 1414
Регистрация: 01.02.2015
Сообщений: 11,187
Записей в блоге: 1
31.12.2015, 08:06 10
Надо же! А об этой составляющей я как-то и не подумал - упёрся рогом только в работоспособность ReadKey.

+1
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.12.2015, 08:06

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Программа не реагирует на нажатие кнопки
Я совершенный дилетант и прошу помощи. При нажатии на кнопку button4 в моем представлении должен...

Макрос и программа, считывающая нажатие клавиш
На языке ассемблера: 1) напишите макрос print str, выводящий строку символов str на экран в...

Программа эмулирует нажатие клавиш клавиатуры в неактивном окне
Всем привет! Требуется написать программу которая эмулирует нажатие клавиш клавиатуры в неактивном...

Программа не видит нажатие клавиш которые заданные формой
Доброго времени суток.У меня есть вопрос:я &quot;написал&quot; программу ,которая при нажатии на клавишу (P)...

Отловить нажатие определенной комбинации клавиш, даже когда программа не в фокусе
Бодрого дня или ночи! :D Написал программу и теперь нузно разобраться как сделать в ней управление...

Нажатие клавиш вне формы (глобальный перехват сочетания клавиш)
Всем доброго времени суток! Задумал сделать значок раскладки клавы, но беда в том, что если...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.