Board logo

标题: [转载]CMD获取当前光标坐标、位置 [打印本页]

作者: 523066680    时间: 2021-5-7 08:56     标题: [转载]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
  1. @echo off
  2. for /F "delims=#" %%a in ('"prompt #$E# & for %%a in (1) do rem"') do set "ESC=%%a"
  3. call :get_cursor_pos
  4. exit /b
  5. :get_cursor_pos
  6. set "response="
  7. set pos=2
  8. :_get_loop
  9. REM *** Request Cursor position
  10. <nul set /p "=%ESC%[6n"
  11. FOR /L %%# in (1 1 %pos%) DO pause < CON > NUL
  12. for /F "tokens=1 skip=1 eol=" %%C in ('"REPLACE /W ? . < con"') DO (
  13.     set "char=%%C"
  14. )
  15. set "response=%response%%char%"
  16. set /a pos+=1
  17. if "%char%" NEQ "R" goto :_get_loop
  18. set response
  19. exit /b
复制代码
其他参考:
https://www.dostips.com/forum/viewtopic.php?t=9454
作者: CrLf    时间: 2021-11-4 22:47

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

更多玩法自己摸索:
https://blog.csdn.net/lano2088/article/details/51985563
作者: a20150604    时间: 2021-11-4 23:29

本帖最后由 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 编译测试
  1. #include <stdbool.h>
  2. #include <windows.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
  7. #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
  8. #endif
  9. #ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
  10. #define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
  11. #endif
  12. #ifndef DISABLE_NEWLINE_AUTO_RETURN
  13. #define DISABLE_NEWLINE_AUTO_RETURN 0x0008
  14. #endif
  15. #define ESC "\x1b"
  16. #define CSI "\x1b["
  17. #define R(mul,shift,x,y) \
  18.     _=x; \
  19.     x -= mul*y>>shift; \
  20.     y += mul*_>>shift; \
  21.     _ = 3145728-x*x-y*y>>11; \
  22.     x = x*_>>10; \
  23.     y = y*_>>10;
  24. int8_t b[1760], z[1760];
  25. char c[1760][100];
  26. bool EnableVTMode();
  27. void HSV2RGB_int(int h, int s, int v, int* r, int* g, int* b);
  28. int main() {
  29. //First, enable VT mode
  30. bool fSuccess = EnableVTMode();
  31. if (!fSuccess) {
  32. printf("Unable to enter VT processing mode. Quitting.\n");
  33. return -1;
  34. }
  35. HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  36. if (hOut == INVALID_HANDLE_VALUE) {
  37. printf("Couldn't get the console handle. Quitting.\n");
  38. return -1;
  39. }
  40. // <nul set /p "=%_ESC%[?25l" & REM _ESC [ ? 25 l    DECTCEM    Text Cursor Enable Mode Hide    Hide the cursor
  41. printf("\x1b[?25l");    //  Text Cursor Enable Mode Hide    Hide the cursor
  42. char scr_buff[1760 * 100 + 1], str1[2], str[20];
  43. str1[1] = '\0';
  44. strcpy(scr_buff, "");
  45. int sA = 1024, cA = 0, sB = 1024, cB = 0, _;
  46. int i, j, k;
  47. int t;
  48. int h, s, v, r, g, bb;
  49. h = 120, s = 100;
  50. for (;;) {
  51. h += 1; h %= 360;
  52. strcpy(scr_buff, "\x1b[1;1H");
  53. memset(b, 32, 1760);  // text buffer
  54. memset(c, 0, 1760 * 100);  // text buffer
  55. for (i = 0; i < 1760; i++) c[i][0] = ' ';
  56. memset(z, 127, 1760);   // z buffer
  57. int sj = 0, cj = 1024;
  58. for (j = 0; j < 90; j++) {
  59. int si = 0, ci = 1024;  // sine and cosine of angle i
  60. for (i = 0; i < 324; i++) {
  61. int R1 = 1, R2 = 2048, K2 = 5120 * 1024;
  62. int x0 = R1 * cj + R2,
  63. x1 = ci * x0 >> 10,
  64. x2 = cA * sj >> 10,
  65. x3 = si * x0 >> 10,
  66. x4 = R1 * x2 - (sA * x3 >> 10),
  67. x5 = sA * sj >> 10,
  68. x6 = K2 + R1 * 1024 * x5 + cA * x3,
  69. x7 = cj * si >> 10,
  70. x = 40 + 30 * (cB * x1 - sB * x4) / x6,
  71. y = 12 + 15 * (cB * x4 + sB * x1) / x6,
  72. N = (-cA * x7 - cB * ((-sA * x7 >> 10) + x2) - ci * (cj * sB >> 10) >> 10) - x5 >> 7;
  73. int o = x + 80 * y;
  74. int8_t zz = (x6 - K2) >> 15;
  75. if (22 > y && y > 0 && x > 0 && 80 > x && zz < z[o]) {
  76. z[o] = zz;
  77. t = N > 0 ? N : 0;
  78. v = t << 3; // << 3 <--> * 8 <--> * 100 / 12;
  79. HSV2RGB_int(h, s, v, &r, &g, &bb);
  80. sprintf(c[o], " [48;2;%d;%d;%dm ", r, g, bb);   // 21=255/12
  81. c[o][0] = '\x1b';
  82. strcat(c[o], "\x1b[48;2;0;0;0m");
  83. }
  84. R(5, 8, ci, si)  // rotate i
  85. }
  86. R(9, 7, cj, sj)  // rotate j
  87. }
  88. for (k = 0; 1761 > k; k++) {
  89. strcat(scr_buff, (k % 80 ? (c[k]) : "\n"));  // putchar(k % 80 ? b[k] : 10);
  90. }
  91. R(5, 7, cA, sA);
  92. R(5, 8, cB, sB);
  93. usleep(1000);
  94. printf("%s", scr_buff);
  95. }
  96. }
  97. // h: [0,360]; s: [0,100]; v:[0,100]; r,g,b:[0,255]
  98. void HSV2RGB_int(int h, int s, int v, int* r, int* g, int* b) {
  99. const int zoom = 100;
  100. h = h < 0 ? h % 360 + 360 : (h >= 360 ? h % 360 : h);
  101. s = s < 0 ? 0 : (s > zoom ? zoom : s);
  102. v = v < 0 ? 0 : (v > zoom ? zoom : v);
  103. int r1, g1, b1;
  104. int c = round(1.0 * v * s / zoom);
  105. int h_ = h % 360 / 60;
  106. int u = (zoom * h / 60) % (zoom * 2) - zoom * 1;
  107. int t = u >> 31;
  108. int x = round(1.0 * c * (zoom * 1 - ((t & (-u)) | (~t & u))) / zoom);
  109. int m = v - c;
  110. switch (h_) {
  111. case 0:
  112. r1 = c, g1 = x, b1 = 0;
  113. break;
  114. case 1:
  115. r1 = x, g1 = c, b1 = 0;
  116. break;
  117. case 2:
  118. r1 = 0, g1 = c, b1 = x;
  119. break;
  120. case 3:
  121. r1 = 0, g1 = x, b1 = c;
  122. break;
  123. case 4:
  124. r1 = x, g1 = 0, b1 = c;
  125. break;
  126. case 5:
  127. r1 = c, g1 = 0, b1 = x;
  128. break;
  129. }
  130. *r = round((r1 + m) * 255.0 / zoom); *g = round((g1 + m) * 255.0 / zoom); *b = round((b1 + m) * 255.0 / zoom);
  131. }
  132. bool EnableVTMode() {
  133. // Set output mode to handle virtual terminal sequences
  134. HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  135. if (hOut == INVALID_HANDLE_VALUE) {
  136. return 0;
  137. }
  138. DWORD dwMode = 0;
  139. if (!GetConsoleMode(hOut, &dwMode)) {
  140. return 0;
  141. }
  142. dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
  143. if (!SetConsoleMode(hOut, dwMode)) {
  144. return 0;
  145. }
  146. return 1;
  147. }
复制代码

作者: netbenton    时间: 2021-11-8 23:18

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





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