返回列表 发帖

[转载]CMD获取当前光标坐标、位置

本帖最后由 523066680 于 2021-5-7 09:03 编辑

偶然看到的一个问答
Yay! I had given up hope of ever getting a pure batch solution. Nicely done.

get-cursor-position-via-windows-10-console-vt-100-escape-sequence
@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
for /F "tokens=1 skip=1 eol=" %%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 /bCOPY
其他参考:
https://www.dostips.com/forum/viewtopic.php?t=9454
1

评分人数

[url=][/url]

牛逼,竟然还能用Escape屏幕控制码。但为什么 <nul set /p "=%ESC%[6n" 能将内容回填到StdIn?

更多玩法自己摸索:
https://blog.csdn.net/lano2088/article/details/51985563
1

评分人数

TOP

本帖最后由 a20150604 于 2021-11-5 00:11 编辑

微软对 终端 的支持从 WIN10 某版本开始, 仍在持续升级中

https://docs.microsoft.com/en-us ... -terminal-sequences

https://devblogs.microsoft.com/c ... y/windows-terminal/

EnableVTMode 应用例:
在 WIN10 控制台显示一个变色甜甜圈(甜甜圈代码 为 转载, 我加了 WIN10 终端开启代码, 变色), Dev-C++ 5.11 编译测试
#include <stdbool.h>
#include <windows.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
#endif
#ifndef DISABLE_NEWLINE_AUTO_RETURN
#define DISABLE_NEWLINE_AUTO_RETURN 0x0008
#endif
#define ESC "\x1b"
#define CSI "\x1b["
#define R(mul,shift,x,y) \
    _=x; \
    x -= mul*y>>shift; \
    y += mul*_>>shift; \
    _ = 3145728-x*x-y*y>>11; \
    x = x*_>>10; \
    y = y*_>>10;
int8_t b[1760], z[1760];
char c[1760][100];
bool EnableVTMode();
void HSV2RGB_int(int h, int s, int v, int* r, int* g, int* b);
int main() {
//First, enable VT mode
bool fSuccess = EnableVTMode();
if (!fSuccess) {
printf("Unable to enter VT processing mode. Quitting.\n");
return -1;
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE) {
printf("Couldn't get the console handle. Quitting.\n");
return -1;
}
// <nul set /p "=%_ESC%[?25l" & REM _ESC [ ? 25 l    DECTCEM    Text Cursor Enable Mode Hide    Hide the cursor
printf("\x1b[?25l");    //  Text Cursor Enable Mode Hide    Hide the cursor
char scr_buff[1760 * 100 + 1], str1[2], str[20];
str1[1] = '\0';
strcpy(scr_buff, "");
int sA = 1024, cA = 0, sB = 1024, cB = 0, _;
int i, j, k;
int t;
int h, s, v, r, g, bb;
h = 120, s = 100;
for (;;) {
h += 1; h %= 360;
strcpy(scr_buff, "\x1b[1;1H");
memset(b, 32, 1760);  // text buffer
memset(c, 0, 1760 * 100);  // text buffer
for (i = 0; i < 1760; i++) c[i][0] = ' ';
memset(z, 127, 1760);   // z buffer
int sj = 0, cj = 1024;
for (j = 0; j < 90; j++) {
int si = 0, ci = 1024;  // sine and cosine of angle i
for (i = 0; i < 324; i++) {
int R1 = 1, R2 = 2048, K2 = 5120 * 1024;
int x0 = R1 * cj + R2,
x1 = ci * x0 >> 10,
x2 = cA * sj >> 10,
x3 = si * x0 >> 10,
x4 = R1 * x2 - (sA * x3 >> 10),
x5 = sA * sj >> 10,
x6 = K2 + R1 * 1024 * x5 + cA * x3,
x7 = cj * si >> 10,
x = 40 + 30 * (cB * x1 - sB * x4) / x6,
y = 12 + 15 * (cB * x4 + sB * x1) / x6,
N = (-cA * x7 - cB * ((-sA * x7 >> 10) + x2) - ci * (cj * sB >> 10) >> 10) - x5 >> 7;
int o = x + 80 * y;
int8_t zz = (x6 - K2) >> 15;
if (22 > y && y > 0 && x > 0 && 80 > x && zz < z[o]) {
z[o] = zz;
t = N > 0 ? N : 0;
v = t << 3; // << 3 <--> * 8 <--> * 100 / 12;
HSV2RGB_int(h, s, v, &r, &g, &bb);
sprintf(c[o], " [48;2;%d;%d;%dm ", r, g, bb);   // 21=255/12
c[o][0] = '\x1b';
strcat(c[o], "\x1b[48;2;0;0;0m");
}
R(5, 8, ci, si)  // rotate i
}
R(9, 7, cj, sj)  // rotate j
}
for (k = 0; 1761 > k; k++) {
strcat(scr_buff, (k % 80 ? (c[k]) : "\n"));  // putchar(k % 80 ? b[k] : 10);
}
R(5, 7, cA, sA);
R(5, 8, cB, sB);
usleep(1000);
printf("%s", scr_buff);
}
}
// h: [0,360]; s: [0,100]; v:[0,100]; r,g,b:[0,255]
void HSV2RGB_int(int h, int s, int v, int* r, int* g, int* b) {
const int zoom = 100;
h = h < 0 ? h % 360 + 360 : (h >= 360 ? h % 360 : h);
s = s < 0 ? 0 : (s > zoom ? zoom : s);
v = v < 0 ? 0 : (v > zoom ? zoom : v);
int r1, g1, b1;
int c = round(1.0 * v * s / zoom);
int h_ = h % 360 / 60;
int u = (zoom * h / 60) % (zoom * 2) - zoom * 1;
int t = u >> 31;
int x = round(1.0 * c * (zoom * 1 - ((t & (-u)) | (~t & u))) / zoom);
int m = v - c;
switch (h_) {
case 0:
r1 = c, g1 = x, b1 = 0;
break;
case 1:
r1 = x, g1 = c, b1 = 0;
break;
case 2:
r1 = 0, g1 = c, b1 = x;
break;
case 3:
r1 = 0, g1 = x, b1 = c;
break;
case 4:
r1 = x, g1 = 0, b1 = c;
break;
case 5:
r1 = c, g1 = 0, b1 = x;
break;
}
*r = round((r1 + m) * 255.0 / zoom); *g = round((g1 + m) * 255.0 / zoom); *b = round((b1 + m) * 255.0 / zoom);
}
bool EnableVTMode() {
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE) {
return 0;
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode)) {
return 0;
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode)) {
return 0;
}
return 1;
}COPY
1

评分人数

    • 523066680: 每次都这么惊艳PB + 12 技术 + 1

TOP

小提速,同可时也可以用来获取最大的行,列值。
@echo off&setlocal enabledelayedexpansion
::文本只能保存为ansi编码,其它编码可能出错。
::Win 10 下测试通过。
for /F "tokens=1 delims=#" %%a in ('"prompt #$E# & echo on & for %%b in (1) do rem"') do set "ESC=%%a"
set/p=%ESC%[255;255H<nul
for /l %%b in (2,1,7) do (
if "!K!" neq "R" (
set /p=%ESC%[6n<nul
(for /l %%a in (1,1,%%b) do pause>nul
for /f "tokens=2 delims=键" %%c in ('"xcopy /w . 2>nul"') do set K=%%c
set str=!str!!k!
)<con
)
)
set /p in=当前窗口显示最大行;列:!str!,回车退出COPY
1

评分人数

TOP

返回列表