Имеем: консольное Win32-приложение, написанное в Borland C++ 5.02.
Необходимо: отлавливать нажатия клавиш на клавиатуре в русской раскладке.
Проблема: при использовании функции getch() все нормально, если вводятся цифры, знаки препинания и
строчные/прописные буквы латиницы - в этом случае getch() возвращает целочисленное значение ASCII-кода соответствующего символа. Но все меняется, когда мы переключаемся в режим ввода кириллицы - цифры и спец. символы вводятся по-прежнему нормально, а вот если нажимается какая-нибудь русская буква, то: 1) она генерирует два байта, причем первый байт - нулевой ('\0'), а второй равен ASCII-коду соответствующей русской буквы; 2) и даже это соблюдается не для всех клавиш: таким образом, например, не ловятся буквы 'х', 'ъ', 'ж', 'э', 'б' и 'ю' - вместо них возвращаются ASCII-коды символов "[];',." ... ........при компиляции того же самого под TC3 все проходит чисто и гладко... На ум уже всякое лезет - и UNICODE, и то, что getch() все-таки больше DOS-овская функция, а не форточная... тестилось под платформами Win98 SE и Win2000 SP4. Результат одинаковый.
Вопрос: можно ли как-то обойти поставленную проблему? Т.е. существуют ли другие функции, аналогичные getch() (аналогичные - т.е. ожидающие нажатия клавиши и возвращающие код символа без эха на экран), которые делали бы то же самое, но корректно? Вообще-то, можно, конечно, пропускать нулевой символ и анализировать следующий за ним, но буквы 'х', 'ъ', 'ж', 'э', 'б' и 'ю' мы все равно в таком случае не поймаем...
Перехват русских букв в консоли Win32
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
-
- Сообщения: 38
- Зарегистрирован: 21 июн 2004, 02:59
- Откуда: Saratov
- Контактная информация:
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Как задача стоит вообще?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
-
- Сообщения: 38
- Зарегистрирован: 21 июн 2004, 02:59
- Откуда: Saratov
- Контактная информация:
пффф... цель всех махинаций до безобразия проста - нужно иметь возможность вводить символы кириллицы при включенной русской раскладке, НО без_эха_на_экран. То есть нажал букву - получил ее код... мне тут посоветовали WinAPI заюзать - ReadConsoleInput... что это и с чем его едят - еще не смотрел, времени пока не очень много было... но... может быть, можно обойтись стандартными средствами BC++ 5.02?.. честно говоря, немного непонятен глюк getch()-а... в чем он проявляется и условия - см. пост #1...Romeo писал(а):Как задача стоит вообще?
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Глюк как раз понятен. Не все скан коды можно закодировать восемью битами, потому некторые систеные сканкоды двух байтные, первый символ 0. Так было и в DOSе. Потому следующий код вполне уместен при использовании getch под DOS.
А вот как бороться с этим глюком под Windows не совсем очевидно...
Код: Выделить всё
char ch;
BOOL isSystem = FALSE;
// очищаем буфер чтобы не было его переполнения,
// которое сопровождается противным писком писиспикера.
while (kbhit())
{
getch();
}
// читаем символ
ch = getch();
// Проверяем на системность.
if (ch == 0)
{
ch = getch();
isSystem = TRUE;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
-
- Сообщения: 38
- Зарегистрирован: 21 июн 2004, 02:59
- Откуда: Saratov
- Контактная информация:
В DOS-е для хранения всех символов использовалось 8 бит - модифицированная альтернативная кодировка ГОСТа (кодовая страница 866), которая включала в себя и кириллицу в том числе. Т.е. кириллица была полноправным множеством символов кодовой таблицы, и кодировались русские буквы одним байтом. В Windows - с его кодовой таблицей 1251 - ситуация та же самая: были убраны за ненадобностью символы псевдографики, и изменились ASCII-коды символов кириллицы, но в кодовой таблице они так и остались...Romeo писал(а):Глюк как раз понятен. Не все скан коды можно закодировать восемью битами, потому некторые систеные сканкоды двух байтные, первый символ 0. Так было и в DOSе.
Можно понять, скажем, что для клавиш системного назначения генерируется двухбайтовый код. Да и то - не для всех: скажем, F1==0,59; Right Arrow==0,77, а вот BackSpace==8; ESC=27...
Но вот когда речь заходит о русских буквах - тут уж увольте! Они никак не системные! И располагаются на тех же клавишах, что и латинский алфавит... Но почему-то генерируются именно расширенные коды, второй байт которых равен ASCII-коду данной нажатой буквы в кодировке 866 страницы, а первый - нулевой. То есть для буквы 'я' первый байт==0, второй==239. Для буквы 'г' первый байт==0, второй==163 (note: как в 866 кодовой таблице!).
Ладно, все было бы легко и просто, если таким образом можно было бы поймать ВСЕ русские буквы - откидываем первый байт, анализируем второй... НО: при попытке ввести букву русскую 'х' мне возвращается однобайтовый код символа '[', равный 91. При попытке ввести 'ж' мне возвращается код символа ';', равный 59. ОДНОБАЙТОВЫЕ!..