Особенности реализации SysGetKey() в Open Object REXX под Windows

Продолжая тему предыдущего сообщения, надо сказать, что реализация SysGetKey() в Open Object REXX под Windows имеет естественные отличия от своего прародителя из OS/2, связанные с отличиями операционных систем. При этом она не только унаследовала все его недостатки, но и приобрела новые, один из которых напрочь перекрывает возможность использования даже того несовершенного решения, которое предложено в последнем тестовом примере предыдущего сообщения.
---

Приведённый ниже тест позволяет убедиться в этом.

Тест № 4:

 /* Sample4.cmd - test of SysGetKey() */
 parse version _ver
 say _ver
 say SysVersion()
 say 'RexxUtil v.'||SysUtilVersion()
 say 'Press Esc to quit'
 _key = '';
 do while (_key \== '1B'x)
    _key = SysGetKey('NOECHO');
    say '_key="'||_key~c2x||'"x'
 end;
 exit;
 ::requires "rexxutil" library

Условия выполнения теста:
  • кодовая страница консоли - CP866 или CP1251
  • раскладка клавиатуры - RU441
  • клавиатура переключена на латиницу
  • CapsLock выключен
Использованы следующие цвета:
  • чёрный - текст, выводимый на экран во время выполнения
  • зелёный - комментарии
  • красный - символы кириллицы, соответствующие клавишам после переключения клавиатуры на кириллицу
Пустые строки вставлены для удобства.

Выполнение теста № 4:

 C:\>Sample4.rex
 REXX-ooRexx_4.2.0(MT)_32-bit 6.04 22 Feb 2014
 WindowsNT 6.01
 RexxUtil v.4.2.0
 Press Esc to quit
              <--- нажата клавиша 2
 _key="32"x   => символ "2" (DIGIT TWO)
              <--- нажата комбинация клавиш Shift+2
 _key="40"x   => символ "@" (COMMERCIAL AT)
              <--- нажата комбинация клавиш Ctrl+2
 _key="00"x   => первый символ сканкода "0003"x
 _key="03"x   => второй символ сканкода "0003"x
              <--- нажата комбинация клавиш Alt+2
 _key="32"x   => символ "2" (DIGIT TWO)

              <--- нажата клавиша F1
 _key="00"x   => первый символ сканкода "003B"x
 _key="3B"x   => второй символ сканкода "003B"x
              <--- нажата комбинация клавиш Shift+F1
 _key="00"x   => первый символ сканкода "0054"x
 _key="54"x   => второй символ сканкода "0054"x
              <--- нажата комбинация клавиш Ctrl+F1
 _key="00"x   => первый символ сканкода "005E"x
 _key="5E"x   => второй символ сканкода "005E"x
              <--- нажата комбинация клавиш Alt+F1
 _key="00"x   => первый символ сканкода "0068"x
 _key="68"x   => второй символ сканкода "0068"x

              <--- нажата клавиша GrayArrowUp
 _key="E0"x   => первый символ сканкода "E048"x
 _key="48"x   => второй символ сканкода "E048"x
              <--- нажата комбинация клавиш Shift+GrayArrowUp
 _key="E0"x   => первый символ сканкода "E048"x
 _key="48"x   => второй символ сканкода "E048"x
              <--- нажата комбинация клавиш Ctrl+GrayArrowUp
 _key="E0"x   => первый символ сканкода "E08D"x
 _key="8D"x   => второй символ сканкода "E08D"x
              <--- нажата комбинация клавиш Alt+GrayArrowUp
 _key="00"x   => первый символ сканкода "0098"x
 _key="98"x   => второй символ сканкода "0098"x

              <--- нажата клавиша h
 _key="68"x   => символ "h" (LATIN SMALL LETTER H)
              <--- нажата комбинация клавиш Shift+h
 _key="48"x   => символ "H" (LATIN CAPITAL LETTER H)
              <--- нажата комбинация клавиш Ctrl+h
 _key="08"x   => управляюший символ BS (BACKSPACE)
              <--- нажата комбинация клавиш Alt+h
 _key="68"x   => символ "h" (LATIN SMALL LETTER H)

              <--- переключаем клавиатуру на кириллицу
              <--- нажата клавиша р
              <--- нажата клавиша Enter
 _key="E0"x   => символ "р" (CYRILLIC SMALL LETTER ER)
 _key="0D"x   => управляюший символ CR (CARRIAGE RETURN)
              <--- нажата комбинация клавиш Shift+р
 _key="90"x   => символ "Р" (CYRILLIC CAPITAL LETTER ER)
              <--- нажата комбинация клавиш Ctrl+р
 _key="08"x   => управляюший символ BS (BACKSPACE)
              <--- нажата комбинация клавиш Alt+р
              <--- нажата клавиша Enter
 _key="E0"x   => символ "р" (CYRILLIC SMALL LETTER ER)
 _key="0D"x   => управляюший символ CR (CARRIAGE RETURN)

              <--- нажата клавиша GrayArrowUp
 _key="E0"x   => первый символ сканкода "E048"x
 _key="48"x   => второй символ сканкода "E048"x
              <--- нажата клавиша р
              <--- переключаем клавиатуру на латиницу
              <--- нажата комбинация клавиш Shift+h
 _key="E0"x   => символ "р" (CYRILLIC SMALL LETTER ER)
 _key="48"x   => символ "H" (LATIN CAPITAL LETTER H)

              <--- нажата комбинация клавиш Ctrl+с
 _key="03"x   => управляюший символ EOT (END OF TEXT)

              <--- нажата клавиша Esc
 _key="1B"x   => управляюший символ ESC (ESCAPE)
 C:\>

Результаты теста отличаются от аналогичного теста под OS/2:
  • комбинация клавиши Alt с любой символьной клавишей срабатывает как простое нажатие на символьную клавишу,
  • нажатие комбинации клавиш Ctrl+c вместо ожидаемого прерывания выполнения и вызова обработки условия HALT возвращает управляющий символ EOT (END OF TEXT),
  • нет возврата из функции SysGetKey() после первого нажатия на клавишу со строчной буквой кириллицы "р" (SMALL CYRILLIC LETTER ER). Возврат из функции происходит после следующего нажатия на любую клавишу; в качестве возвращаемого значения используется символ "р" (SMALL CYRILLIC LETTER ER). Возврат значения следующего нажатия происходит при повторном вызове функции SysGetKey() без обращения к буферу клавиатуры.
Такая реализация функции SysGetKey() не оставляет надежд на то, что можно каким-то способом отличить нажатия клавиш расширенной функциональности от нажатия указанной клавиши национального алфавита без привлечения стронних библиотек.
---

Смотри также:
Особенности реализации SysGetKey() в REXX/Object REXX под OS/2