通过Windows 10控制台VT-100转义序列获取光标位置

问题描述 投票:4回答:2

我正在使用Windows 10控制台中对VT-100转义序列的新(有限)支持。支持的序列记录在https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx

尤其是以下报告当前光标位置的序列引起了我的兴趣。

ESC[6n - responds with ESC[<n>;<m>R, 
         where <n> is the row number, and <m> the column number

响应作为键盘输入传递出去,并显示在屏幕上,但是我不知道如何以编程方式利用这些信息。理想情况下,我想从批处理文件中将<n><m>值放入环境变量中。

但是如果任何人都可以演示如何使用任何语言捕获变量,那么我也许就能利用这些知识来制定有效的批处理文件策略。

我可以使用下面的简单脚本ANSI.BAT来接近

@echo off
setlocal enableDelayedExpansion

for /f "delims=" %%C in (
  'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x1B"'
) do set "esc=%%C"
set "csi=%esc%["

echo(Inquiry:%csi%6n
set /p "pos="
echo response=!pos:%esc%=ESC!

-输出-

C:\test>ansi
Inquiry:
^[[3;9R
response=ESC[3;9R

C:\test>

一旦我将响应包含在变量中,便可以使用FOR / F轻松解析出值。我遇到的问题是,在响应出现在屏幕上之后,我必须手动按<Enter>键才能终止SET / P语句的输入。我为从这里去哪里感到困惑...

EDIT-最后一个要求:我不希望查询响应出现在屏幕上,因为这会打乱屏幕并更改光标位置。我怀疑这可能是最难破解的螺母,对于纯批处理来说可能是不可能的。

batch-file windows-console ansi-escape
2个回答
2
投票

我没有Windows 10,所以我无法完成任何测试。但是,如果Ansi ESC[6n序列的响应是用ESC[<n>;<m>R字符填充键盘输入缓冲区,则仅需要向该输入添加Enter键,以便通过SET /P进行读取。命令,这可以通过SendKeys JScript方法完成。

我还使用了一种更简单的方法来获取变量中的ESC字符。

EDIT:我根据注释对代码进行了修改...

@if (@CodeSegment == @Batch) @then

@echo off
title Ansi Test
setlocal EnableDelayedExpansion

for /F %%a in ('echo prompt $E ^| cmd') do set "esc=%%a"
set "csi=%esc%["

echo Inquiry:%csi%6n
cscript //nologo //E:JScript "%~F0"
set /p "pos=" > NUL
echo response=!pos:%esc%=ESC!

@end

var sh = WScript.CreateObject("WScript.Shell");
sh.AppActivate("Ansi Test");
sh.SendKeys("{ENTER}");

请发布结果...


0
投票

它与通过使用XCOPYREPLACE读取响应一起工作。

我在这里使用replace,也避免了语言相关的问题。

@echo off
for /F "delims=#" %%a in ('"prompt #$E# & for %%a in (1) do rem"') do set "ESC=%%a"

call :get_cursor_pos
exit /b

:get_cursor_pos
set "response="
set pos=2

:_get_loop
REM *** Request Cursor position
<nul set /p "=%ESC%[6n" 
FOR /L %%# in (1 1 %pos%) DO pause < CON > NUL

set "char=;"
for /F "tokens=1 skip=1 delims=*" %%C in ('"REPLACE /W ? . < con"') DO (
    set "char=%%C"
)
set "response=%response%%char%"
set /a pos+=1
if "%char%" NEQ "R" goto :_get_loop

set response
exit /b

诀窍是

© www.soinside.com 2019 - 2024. All rights reserved.