1 (изменено: smaharbA, 2012-09-14 16:26:10)

Тема: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

есть пакетник


echo off
choice /m "%~1" /c "%~2" /n
exit /b %ERRORLEVEL%

вызывается примерно так


call utilit\ask 2345678q "Выберете режим"
if errorlevel 8 goto ...
...
if errorlevel 1 goto ...

Дайте идею, что бы при нажатии Q либо Й - отрабатывал один и тот же код возврата, без переделки строки вызова (вызывающий пакетный файл сторонний и изменению не подлежит)

+ Можно конечно задействовать debug.exe, но не хотелось городить огород

Я конечно далек от мысли... (с)

2

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

Не совсем то, и не совсем красиво, но… зато работает.

@echo off
setlocal enableextensions enabledelayedexpansion
choice.exe /m:"Текст" /c:YNНТнт /n
set /a iChoice = %errorlevel%
for %%i in (1, 3, 5) do if %iChoice% equ %%i echo Yes
for %%i in (2, 4, 6) do if %iChoice% equ %%i echo No
endlocal
exit /b 0

что бы при нажатии Q либо Й - отрабатывал один и тот же код возврата

Без переделки choice.exe — вряд ли. В первых версиях choice и вовсе русские буквы не воспринимал ни под каким соусом.

3 (изменено: smaharbA, 2012-09-14 18:16:09)

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

alexii - Вы не поняли - вызов пакетника заранее не известен и вызывающую строку менять нет возможности
даже если сделать транслит, то к примеру входная строка 2345678q замениться на 2345678q2345678й - что не будет работать

еще попробую пояснить, есть вызывающий пакетник (его нет возможности изменять), он может вызвать текущий с любым набором выбора к примеру попадет выбор типа  23456QXZ179АБВ - изменить его можно только внутри вызываемого так что бы код возврата был для QXZ=ЙЧЯ и так же АБВ=F<D

Я конечно далек от мысли... (с)

4

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

smaharbA пишет:

alexii - Вы не поняли…

Да, не понял.

smaharbA пишет:

даже если сделать транслит, то к примеру входная строка 2345678q замениться на 2345678q2345678й - что не будет работать

Почему не будет? Только будет «2345678q2345678Й2345678й». Так ведь можно?


smaharbA пишет:

к примеру попадет выбор типа  23456QXZ179АБВ

Тогда получается, что логика:

что бы при нажатии Q либо Й - отрабатывал один и тот же код возврата

не имеет смысла.

5 (изменено: smaharbA, 2012-09-14 22:29:03)

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

смысл простой - сканкоды

т.е. - я не могу изменить передачу параметров, могу только повлиять на исполнение (код возврата)
параметры мне передает пакетник,  изменить который я не могу
т.е. мне передали вопрос о нажатии YN - мой пакетник дожен одинаково отработать на нажатия как YN так и НТ, но что будет передано я не могу предвидеть
т.е. нужна одинаковая реакция на выбор как в английской раскладке, так и русской, но передается заранее неизвестный набор ключей

Я конечно далек от мысли... (с)

6

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

smaharbA, я имею в виду, что, если, как Вы приводите выше пример, на вход действительно может быть передан смешанный набор из латиницы и кириллицы, например, вида «YNДН» — попытка трактовать кириллицу как латиницу приведёт не к тому, что ожидалось.

7 (изменено: smaharbA, 2012-09-15 01:24:52)

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

упростим (для начала)
на вход приходит только набор из цифр и букв английского алфавмиа - как вернуть ответ для X и Ч одинаковый ?
реакция на нажатие клавишь должна быть как у choice - одна клавиша без ентеров
какой набор кодов будет получен заранее неизвестно

набор == перечень возможных вариантов выбора
пользователь должен мочь получить один и тот же результат при любой (из двух) текушей раскладке

конечно есть вариант цикла с транслированием и ожиданием в чюсе 1 сек, но это даст нечеткое срабатование

Я конечно далек от мысли... (с)

8

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

Вот вариант скрипта для "упрощённого варианта":

@echo off
setlocal enableextensions enabledelayedexpansion

set symb1=qwertyuiopasdfghjklzxcvbnm0123456789
set symb2=йцукенгшщзфывапролдячсмить&#9617;&#9618;&#9619;&#9562;&#9563;&#9564;&#9565;&#9566;&#9567;&#9568;

set outstr=
set instr=%~2
if _%instr%==_ goto usage

:loop1
set insym=%instr:~0,1%
set instr=%instr:~1%

::echo insym = "%insym%"
::echo instr = "%instr%"

set instr1=%symb1%
set instr2=%symb2%

:loop2

set insym1=%instr1:~0,1%
set instr1=%instr1:~1%
set insym2=%instr2:~0,1%
set instr2=%instr2:~1%

if /I not %insym%==%insym1% (
  if not _%instr1%==_ goto loop2
  exit /b 254
)

set outstr=%outstr%%insym1%%insym2%
::echo outstr = "%outstr%"

if not _%instr%==_ goto loop1

choice /m "%~1" /c "%outstr%" /n

set a=%errorlevel%
set /a a=(a+1)/2
::echo a=%a%
exit /b %a%

goto end

:usage
echo Usage: %~nx0 Prompt Symbols

:end
endlocal

Идея в следующем: в строку вариантов выбора после каждого символа латиницы добавляется соответствующий символ кирилицы. errorlevel, который возвращает choice пересчитывается, чтобы соответствовать номерам исходного списка.
В строки symb1 и symb2 можно по аналогии забить символы кирилицы и латиницы, но нужно думать, что лучше делать с символами кирилицы, которым на клавиатуре соответствуют скобки, точки и прочие символы, т.к. choice их в списке указывать не позволяет. Для цифр в symb2 забиты символы псевдографики, которые choice принимает и которые вряд-ли кто-то случайно введёт с клавиатуры.

В CODE в symb2 символы псевдографики почему-то пролазить не хотят, поэтому:
1. я скрипт положил сюда: http://zalil.ru/33754479
2. символы можно набрать так: В Far2 сохранить файл в кодовой таблице CP 866, удалить коды & #9617; & #9618; ... и скопировать символы отсюда: &#9617;&#9618;&#9619;&#9562;&#9563;&#9564;&#9565;&#9566;&#9567;&#9568;
3. В Far2 сохранить файл в кодовой таблице CP 866, поставить курсор на место соответствующего символа (& #9617; и т.д.), зажать Alt, справа на цифровой клавиатуре ввести код соответствующего символа (9617, 9618 ...) и отпустить Alt. Должен будет вставиться соответствующий символ псевдографики.

Ну и, имхо, лучше вариант - написать свой вариант choice на VBS\JS, там будет больше возможностей по реакции на символы.

9

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

в строку вариантов выбора после каждого символа латиницы добавляется соответствующий символ кирилицы.

Добавлять надо как заглавную букву, так и строчную. Choice.exe их различает.

10 (изменено: smaharbA, 2012-09-17 10:54:55)

Re: CMD/BAT:Как заставить choice понимать разную раскладку как одинаковую?

про транслит написано выше, но не подумал про символы псевдографики - спасибо за идею

echo off
setlocal ENABLEDELAYEDEXPANSION
set opt=%~2
if "%opt%"=="" set opt=%~1
call :length "%opt%"
call :translite "%opt%"
choice /c "%opt%%translite%" /m "%~1" /n
set e=%ERRORLEVEL%
if %e% gtr %length% set /a e=%e% - %length%
exit /b %e%

:translite () {
    @@rem Процедура "транслитерации"
    @@rem
    setlocal ENABLEDELAYEDEXPANSION
    set opt=%~1
    set opt=%opt:"='%
    set out=%~0
    if "%out:~0,1%"==":" (
        set out=%out:~1%
        ) else (
        set out=out
        )
    set eng=qwertyuiopasdfghjklzxcvbnm0123456789
    set rus=йцукенгшщзфывапролдячсмить&#9619;&#9474;&#9508;&#9569;&#9570;&#9558;&#9557;&#9571;&#9553;&#9559;
    set ret=
    call :length "%opt%"
    set /a length=%length% - 1
    set charinstr=-1
    for /l %%x in (0,1,%length%) do (
        set x=!opt:~%%x,1!
        call :charinstr "%eng%" "!x!"
        if !charinstr! geq 0 (
            for /l %%y in (!charinstr!,1,!charinstr!) do (
                set ret=!ret!!rus:~%%y,1!
            )
        ) else (
            set ret=!ret!!opt:~%%x,1!
        )
    )
    endlocal & set %out%=%ret%
    exit /b 0
}

:charinstr () {
    setlocal ENABLEDELAYEDEXPANSION
    set opt=%~1
    set opt=%opt:"='%
    set char=%~2
    set out=%~0
    if "%out:~0,1%"==":" (
        set out=%out:~1%
        ) else (
        set out=out
        )
    call :length "%opt%"
    set /a length=%length% - 1
    set ret=-1
    for /l %%x in (0,1,%length%) do (
        set x=!opt:~%%x,1!
        if /i "%char%"=="!x!" (
            set ret=%%~x
            goto break_charinstr
        )
    )
:break_charinstr
    endlocal & set %out%=%ret%
    exit /b 0
}

:length (string) {
    @@rem Процедура определения длины строки
    @@rem
    setlocal
    set opt=%~1
    set opt=%opt:"='%
    set out=%~0
    if "%out:~0,1%"==":" (
        set out=%out:~1%
        ) else (
        set out=out
        )
    set /a n=0
    :loop_len
    if not "%opt%"=="" (
        set opt=%opt:~1%
        set /a n=%n%+1
        goto loop_len
        )
    endlocal & set /a %out%=%n%
    exit /b 0
    }
Я конечно далек от мысли... (с)