Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31

Реализация консольной печатной машины - обработка курсорных стрелок

22.06.2013, 20:11. Показов 1083. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Несмотря на то, что в нижеприведенном коде используются сишные функции, ничего чисто сишного там нет, и всё без затруднений может быть переписано на C++.

C
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
79
80
81
82
83
84
85
86
87
88
89
#include <stdio.h>
#include <conio.h>
#include <windows.h>
 
int main()
{
    unsigned char input=0;
    unsigned short state=0;
 
    COORD curPos={0,0};
    HANDLE hc=GetStdHandle(STD_OUTPUT_HANDLE);
 
    state=GetAsyncKeyState(VK_UP);
 
    for(;;)
    {
        input=getch();
 
        switch(input)
        {
            case 8: // Backspace
            {
                if (curPos.X) curPos.X--;
                printf("\b \b");
                break;
            }
 
            case 13: // Enter
            {
                curPos.X=0;
                curPos.Y++;
                printf("\r\n");
                break;
            }
 
            case 27: // Escape
            {
                return 0;
            }
 
            case 224:
            {
                state=GetAsyncKeyState(VK_UP);
 
                if (state)
                {
                    if (curPos.Y) curPos.Y--;
                    SetConsoleCursorPosition(hc, curPos);
                    getch();
                }
 
                state=GetAsyncKeyState(VK_DOWN);
 
                if (state)
                {
                    curPos.Y++;
                    SetConsoleCursorPosition(hc, curPos);
                    getch();
                }
 
                state=GetAsyncKeyState(VK_LEFT);
 
                if (state)
                {
                    if (curPos.X) curPos.X--;
                    SetConsoleCursorPosition(hc, curPos);
                    getch();
                }
 
                state=GetAsyncKeyState(VK_RIGHT);
 
                if (state)
                {
                    curPos.X++;
                    SetConsoleCursorPosition(hc, curPos);
                    getch();
                }
            }
 
            default:
            {
                printf("%c", input);
                curPos.X++;
            }
        }
    }
 
    return 0;
}
Моя проблема состоит в том, что обработка нажатий курсорных стрелок идет не так, как нужно (см. первый скриншот - происходит 10х нажатие "вниз" и "вверх" соответственно, например). Так как нужна правильная работа программы в обеих, как русской, так и английской раскладках, то я использую WinAPI-шную функцию GetAsyncKeyState. Если в ее возвращаемом значении наименьший бит установлен в единицу, то с момента последнего вызова этой функции соответствующая клавиша была нажата. В следующем тестовом коде:
C
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
#include <stdio.h>
#include <conio.h>
#include <windows.h>
 
void show_bin(unsigned short arg)
{
    unsigned short mask=0x8000;
 
    while(mask)
    {
        printf("%d", arg & mask ? 1 : 0);
        mask=mask>>1;
    }
 
    printf("\n");
}
 
int main()
{
    unsigned char in;
 
    show_bin(GetAsyncKeyState(VK_UP)); // необходимый начальный вызов функции, хотя и без него работает
    printf("\n");
 
    do
    {
        in=getch();
        switch(in)
        {
            case 13:
            {
                printf("enter\n");
                break;
            }
 
            case 8:
            {
                printf("backspace\n");
                break;
            }
 
            case 224:
            {
                show_bin(GetAsyncKeyState(VK_UP));
                show_bin(GetAsyncKeyState(VK_DOWN));
                show_bin(GetAsyncKeyState(VK_LEFT));
                show_bin(GetAsyncKeyState(VK_RIGHT));
                printf("\n");
            }
        }
    } while(in!=27);
 
    return 0;
}
всё обрабатывается корректно (см. второй скриншот). Однако, выходит так, что при первом коде GetAsyncKeyState постоянно возвращает нулевое значение, хотя принцип и логика всё те же. Прошу помочь разобраться.
Миниатюры
Реализация консольной печатной машины - обработка курсорных стрелок   Реализация консольной печатной машины - обработка курсорных стрелок  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.06.2013, 20:11
Ответы с готовыми решениями:

Звук печатной машины
Поиск ни чего не дал поэтому спрашиваю! Как можно сделать так что бы во всех текстовых программах звучал звук печатной машины? Или...

Реализация консольной программы в Qt
У меня есть рабочий код на чистом СИ. Суть программы в том, чтобы из файла рандомно выбирать вопрос, выводить его и варианты ответов к...

Обработка столкновений в консольной игре
Здравствуйте, продолжаю делать свою &quot;терминальную&quot;(консольную) игру на C#. Столкнулся с некоторой проблемой, в частности с обработкой...

3
погромист
 Аватар для coloc
415 / 251 / 30
Регистрация: 27.08.2012
Сообщений: 550
23.06.2013, 00:00
Просто нужно приостановить работу программы на некоторое время, например Sleep( 500 ) или getch()
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
23.06.2013, 17:18  [ТС]
Цитата Сообщение от coloc Посмотреть сообщение
getch()
У меня программа на этом же и завязана - будет ожидать ввода от пользователя.
Цитата Сообщение от coloc Посмотреть сообщение
Sleep( 500 )
А где именно?

Добавлено через 17 часов 10 минут
Разобрался. Точнее, просто довел до правильного поведения. Отчего-то программа выполняет как case 224, так и default, так что я просто в каждый if-блок в case 224 добавил continue. Видимо, есть какие-то тонкости в автономном выполнении программы, потому как при дебаге, когда последовательно переходишь к следующей инструкции, также еще печатается второй байт курсорных стрелок и таких лестниц не наблюдается.
0
0 / 0 / 0
Регистрация: 03.08.2010
Сообщений: 31
23.06.2013, 17:27  [ТС]
И из этого вытекает следующее: когда, например, быстро попеременно нажимаешь русскую 'р' в такой же раскладке и стрелку вправо, то печатаются совсем не те символы (см. скриншот). Думаю, вот сейчас где-то следует вставить Sleep(), правда, не знаю где.
Миниатюры
Реализация консольной печатной машины - обработка курсорных стрелок  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.06.2013, 17:27
Помогаю со студенческими работами здесь

Обработка вывода консольной программы
Здравствуйте. Нужно в Unix системе обработать вывод программы df. А именно получить путь смонтированного USB устройства Все бы хорошо, но я...

Обработка нажатия стрелок клавиатуры
Мне нужно обработать события на клавиши &quot;вверх&quot;, &quot;вниз&quot; &quot;вправо&quot;,&quot;влево&quot;. Объясните пожалуйста по шагам, как это все сделать. Вот мой...

Обработка нажатия клавиш-стрелок
Добрый вечер, я делаю пошаговую демонстрационную программу различных методов сортировок в консоли, но не знаю как сделать так, чтобы при...

Реализация машины тьюринга
Добрый день! Имеется реализация машины Тьюринга на mulisp выражения (4-x)/2y (defun delay (n) (loop ((eql n 0)...

Реализация Машины Тьюринга
Всем привет. Интересует такой вопрос: Как реализовать Машину Тьюринга для преобразования чисел из двоичной системы счисления в...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru