Board logo

标题: [其他] [已解决]批处理怎么做一个可以上下移动的选择框? [打印本页]

作者: ANSL    时间: 2022-4-2 08:27     标题: [已解决]批处理怎么做一个可以上下移动的选择框?

本帖最后由 ANSL 于 2022-4-6 09:32 编辑

选中前[ ]
选中后[X]
按空格选中
再按一下取消选中
选完按Enter
有三个选择框按上下迁换到不同的选择框
选第1个显示1
选第2个显示2
选第3个显示3
作者: idwma    时间: 2022-4-2 16:11

把上次的演进一下
  1. @echo off&setlocal enabledelayedexpansion
  2. set i=0
  3. :l
  4. cls
  5. if %i%==1 set /p "=>" <nul
  6. echo [%_s1%]a
  7. if %i%==2 set /p "=>" <nul
  8. echo [%_s2%]b
  9. if %i%==3 set /p "=>" <nul
  10. echo [%_s3%]c
  11. for /f %%i in ('powershell "[int][Console]::ReadKey(1).key"') do (
  12.     if not %%i==13 (
  13.         if %%i==38 if not %i%==1 set /a i-=1
  14.         if %%i==40 if not %i%==3 set /a i+=1
  15.         if %%i==32 if defined _s!i! (set _s!i!=) else (set _s!i!=x)
  16.         goto :l
  17.     )
  18. )
  19. echo %i%
  20. for /f "delims==" %%i in ('set _s') do echo %%i
  21. pause
复制代码

作者: for_flr    时间: 2022-4-2 17:17

回复 2# idwma
大佬,你那个上下菜单太有趣了,我模仿了一个
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f %%i in ('echo;prompt $h^|cmd') do set "b=%%i"
  4. for /f "delims=U" %%i in ('cmd/u/c echo;唉') do set "t=%%i"
  5. set "s=  "
  6. for /l %%a in (1,1,62) do set "bs=!bs!!b!"
  7. rem 分别定义退格符、制表符、空格、和大量退格符
  8. set c1=选项1
  9. set c2=选项2
  10. set c3=选项3
  11. set c4=选项4
  12. set cn=4
  13. set /a i=cn*1000
  14. set mod=0
  15. rem cn变量表示选项数量,用取余可以让选择框循环的上上下下
  16. rem i变量为了避免成为负数,乘以1000
  17. :l
  18. if %mod%==0 (echo;[%c1%]) else echo;%c1%%s%
  19. if %mod%==1 (echo;[%c2%]) else echo;%c2%%s%
  20. if %mod%==2 (echo;[%c3%]) else echo;%c3%%s%
  21. if %mod%==3 (echo;[%c4%]) else echo;%c4%%s%
  22. rem 每个选项后加一两个空格增加容错率......
  23. for /f %%i in ('powershell "[Console]::ReadKey(1).key"') do (
  24.     if /i %%i neq enter (
  25.         if /i %%i==uparrow  set /a i-=1
  26.         if /i %%i==downarrow  set /a i+=1
  27.         set/a mod=i%%cn
  28.         2>nul echo;!t!!bs! &set /p=!b!<nul
  29.         rem 参考老帖‘多行回退’,代替cls清屏
  30.         goto :l
  31.     )
  32. )
  33. echo %mod%
  34. rem  根据余数call标签函数,略过。
  35. pause
复制代码

作者: ANSL    时间: 2022-4-2 19:03

本帖最后由 ANSL 于 2022-4-2 19:19 编辑

回复 2# idwma我想加个防空选,未选中的样式改成<第一个[]>
选中样式:<第一个[X]>
就是把选中时的>1[]
改成<1[]>
如果空选显示 你空选了!
而且只能选一个!
如多选显示 你多选了!
只能选一个
选第1个显示1
选第2个显示2
选第3个显示3
谢谢大佬!
作者: went    时间: 2022-4-2 22:10

看了这篇彩色显示,撸了一个高亮单选菜单http://www.bathome.net/redirect.php?goto=findpost&pid=252648&ptid=61903
测试的是win11系统
  1. @echo off & cd /d "%~dp0"
  2. call :get_menu "menu-item-1" "menu-item-2" "menu-item-3" "menu-item-4" "menu-item-5"
  3. echo 选择了第%errorlevel%项
  4. pause&exit
  5. REM 选择菜单,参数 菜单列表 ...
  6. :get_menu
  7. set "_n=0"
  8. for %%i in (%*) do set /a "_n+=1"
  9. if "%_cur%"=="" set "_cur=1"
  10. call :show_menu %_cur% %*
  11. echo.
  12. choice /C "WSY" /N /M "WS切换,Y确定"
  13. if "%errorlevel%"=="3" exit /b %_cur%
  14. if "%errorlevel%"=="2" if %_cur% lss %_n% set /a "_cur+=1"
  15. if "%errorlevel%"=="1" if %_cur% gtr 1 set /a "_cur-=1"
  16. cls&goto :get_menu %*
  17. REM 显示菜单
  18. :show_menu
  19. set /a "_i=%~1,_j=1" & shift /1
  20. :L1
  21. if "%~1"=="" goto :eof
  22. if "%_i%"=="%_j%" ( call :show_str 0 255 0 %~1 ) else ( call :show_str 255 255 255 %~1)
  23. shift /1 & set /a "_j+=1" & goto :L1
  24. REM 显示彩色字符串,参数 R,G,B,str
  25. :show_str
  26. echo.[38;2;%~1;%~2;%~3m%~4
  27. goto :eof
复制代码

作者: went    时间: 2022-4-2 22:24

多选菜单
  1. @echo off & cd /d "%~dp0"
  2. setlocal enabledelayedexpansion
  3. call :get_menu "menu-item-1" "menu-item-2" "menu-item-3" "menu-item-4" "menu-item-5"
  4. echo 选择了%_ret%项
  5. pause&exit
  6. REM 多选择菜单
  7. REM [返回值 _ret]
  8. REM [参数 菜单列表 ...]
  9. :get_menu
  10. set "_n=0"
  11. for %%i in (%*) do set /a "_n+=1"
  12. if "%_cur%"=="" set "_cur=1"
  13. call :show_menu %_cur% %*
  14. echo.
  15. choice /C "WSAY" /N /M "WS切换,A标记,Y确定 "
  16. if "%errorlevel%"=="4" ( set "_ret=" & (for /f "tokens=2 delims==_" %%i in ('set _n_ 2^>nul') do set "_ret=!_ret! %%i") & goto :eof)
  17. if "%errorlevel%"=="3" if "!_n_%_cur%!"=="1" ( set "_n_%_cur%=" ) else ( set "_n_%_cur%=1" )
  18. if "%errorlevel%"=="2" if %_cur% lss %_n% set /a "_cur+=1"
  19. if "%errorlevel%"=="1" if %_cur% gtr 1 set /a "_cur-=1"
  20. cls&goto :get_menu %*
  21. REM 显示菜单
  22. REM [参数 选择项 菜单列表 ...]
  23. :show_menu
  24. set /a "_i=%~1,_j=1" & shift /1
  25. :L1
  26. if "%~1"=="" goto :eof
  27. if "%_i%"=="%_j%" ( call :show_str 255 0 0 %~1 & goto :L2)
  28. if "!_n_%_j%!"=="1" ( call :show_str 0 255 0 %~1 & goto :L2)
  29. call :show_str 255 255 255 %~1
  30. :L2
  31. shift /1 & set /a "_j+=1" & goto :L1
  32. REM 显示彩色字符串
  33. REM [参数 R,G,B,str]
  34. :show_str
  35. echo.[38;2;%~1;%~2;%~3m%~4
  36. goto :eof
复制代码

作者: idwma    时间: 2022-4-3 14:09

回复 4# ANSL


    有点绕呀,如果不需要多选,那要按空格选中这步也可以不不需要呀
作者: ANSL    时间: 2022-4-3 14:21

回复 7# idwma
确实有点矛盾
假如你要用多选的选择框启动程序,选1启动1.bat选2启动2.bat选3启动3.bat(可多选)
假如你多选了2和3同时启动2.bat和3.bat
如果你空选了提就示你空选了!这种怎么做?

作者: idwma    时间: 2022-4-3 18:08

回复 8# ANSL

后面两行,大概像这样,也可以参考一下上面wf两位大佬的方法,根据自己的想法尝试改一下
  1. for /f "delims==" %%i in ('set _s') do (
  2. set f=1
  3. if %%i==_s1 (1.bat) else if %%i==_s2 (2.bat) else if %%i==_s3 (3.bat)
  4. )
  5. if not defined f echo 空
复制代码

作者: 5i365    时间: 2022-4-3 18:54

回复 9# idwma


   大侠好, 能用纯ps实现一下吗
作者: idwma    时间: 2022-4-3 21:28

回复 10# 5i365

方法大同小异呀
  1. $menu=@(
  2. ' a'
  3. ' b'
  4. ' c'
  5. )
  6. $menu
  7. $ii=$menu.count*1000
  8. while($i -ne 13){
  9.     $i=[int][Console]::ReadKey(1).key
  10.     if($i -eq 38){$ii--}
  11.     if($i -eq 40){$ii++}
  12.     $mod=$ii%$menu.count
  13.     write-host ' ' -no
  14.     [Console]::SetCursorPosition(0,$mod)
  15.     write-host '>' -no
  16.     [Console]::SetCursorPosition(0,$mod)
  17. }
复制代码

作者: 5i365    时间: 2022-4-3 22:00

回复 11# idwma


   技术牛X 感谢分享,
作者: ANSL    时间: 2022-4-4 18:04

本帖最后由 ANSL 于 2022-4-4 18:06 编辑

回复 9# idwma怎么回事?
只要多选回显就会关闭@ echo off没用

作者: idwma    时间: 2022-4-5 13:28

回复 13# ANSL


    可否看一下你运行的代码
作者: 5i365    时间: 2022-4-5 14:02

回复 11# idwma


   我刚试了一下, 这个报错
作者: idwma    时间: 2022-4-5 14:38

回复 15# 5i365


    运行的代码看一下
作者: 5i365    时间: 2022-4-5 14:55

回复 11# idwma


   我在ISE中试的好像是死循环, 报下面的错
>Exception calling "SetCursorPosition" with "2" argument(s): "句柄无效。
"
At line:16 char:5
+     [Console]::SetCursorPosition(0,$mod)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: ( [], MethodInvocationException
    + FullyQualifiedErrorId : IOException

Exception calling "ReadKey" with "1" argument(s): "Cannot read keys when either application does not have a console or when console input has been redirected from a file
. Try Console.Read."
At line:9 char:5
+     $i=[int][Console]::ReadKey(1).key
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : InvalidOperationException

Exception calling "SetCursorPosition" with "2" argument(s): "句柄无效。
"
At line:14 char:5
+     [Console]::SetCursorPosition(0,$mod)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IOException

>Exception calling "SetCursorPosition" with "2" argument(s): "句柄无效。
"
At line:16 char:5
+     [Console]::SetCursorPosition(0,$mod)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IOException
作者: idwma    时间: 2022-4-5 15:09

回复 17# 5i365


    不太清楚在ise里可能不适用吧
作者: ANSL    时间: 2022-4-5 15:34

回复 14# idwma
  1. @echo off&setlocal enabledelayedexpansion
  2. set i=0
  3. :l
  4. cls
  5. if %i%==1 set /p "=>" <nul
  6. echo [%_s1%]a
  7. if %i%==2 set /p "=>" <nul
  8. echo [%_s2%]b
  9. if %i%==3 set /p "=>" <nul
  10. echo [%_s3%]c
  11. for /f %%i in ('powershell "[int][Console]::ReadKey(1).key"') do (
  12.     if not %%i==13 (
  13.         if %%i==38 if not %i%==1 set /a i-=1
  14.         if %%i==40 if not %i%==3 set /a i+=1
  15.         if %%i==32 if defined _s!i! (set _s!i!=) else (set _s!i!=x)
  16.         goto :l
  17.     )
  18. )
  19. echo %i%
  20. for /f "delims==" %%i in ('set _s') do (
  21. set f=1
  22. if %%i==_s1 (1.bat) else if %%i==_s2 (2.bat) else if %%i==_s3 (3.bat)
  23. )
  24. if not defined f echo 空
复制代码

作者: idwma    时间: 2022-4-5 16:05

回复 19# ANSL


    123bat里的代码是什么样的
作者: ANSL    时间: 2022-4-5 18:42

本帖最后由 ANSL 于 2022-4-5 18:43 编辑

回复 20# idwma
1.bat

  1. @ echo off
  2. echo running 1.bat
  3. pause
  4. exit
复制代码


2.bat
  1. @ echo off
  2. echo running 2.bat
  3. pause
  4. exit
复制代码

3.bat
  1. @ echo off
  2. echo running 3.bat
  3. pause
  4. exit
复制代码

作者: idwma    时间: 2022-4-5 20:06

回复 21# ANSL
  1. @echo off&setlocal enabledelayedexpansion
  2. set i=0
  3. :l
  4. cls
  5. if %i%==1 set /p "=>" <nul
  6. echo [%_s1%]a
  7. if %i%==2 set /p "=>" <nul
  8. echo [%_s2%]b
  9. if %i%==3 set /p "=>" <nul
  10. echo [%_s3%]c
  11. for /f %%i in ('powershell "[int][Console]::ReadKey(1).key"') do (
  12.     if not %%i==13 (
  13.         if %%i==38 if not %i%==1 set /a i-=1
  14.         if %%i==40 if not %i%==3 set /a i+=1
  15.         if %%i==32 if defined _s!i! (set _s!i!=) else (set _s!i!=x)
  16.         goto :l
  17.     )
  18. )
  19. echo %i%
  20. for /f "delims==" %%i in ('set _s') do (
  21. set f=1
  22. if %%i==_s1 (start 1.bat) else if %%i==_s2 (start 2.bat) else if %%i==_s3 (start 3.bat)
  23. )
  24. if not defined f echo 空
  25. pause
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2