如何在C#控制台应用程序中获取光标处的字符
本文关键字:光标 获取 字符 应用程序 控制台 | 更新日期: 2023-09-27 18:28:19
我知道如何将光标设置到控制台中的特定点,同时使用SetCursorPosition或CursorLeft和CursorTop。这不是问题。
但是,我如何获得该点的值?难道没有类似控制台的东西。光标吗?所以我可以把角色放在那个位置?也许类似于:
char c = Console.GetCharAtCursor();
运气不好?
AFAIK,您必须将整个控制台缓冲区读取为二维缓冲区,并使用光标的X和Y坐标作为该缓冲区的索引。参见:
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool GetConsoleScreenBufferInfo(
IntPtr consoleHandle,
out CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo);
你可以在这里阅读缓冲区结构:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
更新:
如果你对使用控制台API编写游戏感兴趣,有人为控制台编写了空间入侵者(实际上是powershell),但所有的API都是托管代码,而不是脚本。他有精灵/路径例程等-来源已经结束http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/
"CursorLeft"answers"CursorTop"有getter,所以您可以直接读取它们:var cleft = Console.CursorLeft
根据MSDN论坛的答案:
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadConsoleOutputCharacter(
IntPtr hConsoleOutput,
[Out] StringBuilder lpCharacter,
uint length,
COORD bufferCoord,
out uint lpNumberOfCharactersRead);
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
}
public static char ReadCharacterAt(int x, int y)
{
IntPtr consoleHandle = GetStdHandle(-11);
if (consoleHandle == IntPtr.Zero)
{
return ''0';
}
COORD position = new COORD
{
X = (short)x,
Y = (short)y
};
StringBuilder result = new StringBuilder(1);
uint read = 0;
if (ReadConsoleOutputCharacter(consoleHandle, result, 1, position, out read))
{
return result[0];
}
else
{
return ''0';
}
}
应用它看起来像这样:
class Program
{
static void Main(string[] args)
{
Console.Clear();
Console.CursorLeft = 0;
Console.CursorTop = 1;
Console.Write("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
char first = ReadCharacterAt(10, 1);
char second = ReadCharacterAt(20, 1);
Console.ReadLine();
}
}
我不喜欢这里为我的简单应用程序发布的长答案,所以我想了一个解决办法——我将整个控制台缓冲区存储在一个2D数组中,然后在数组中进行索引。为我的应用程序工作(在控制台中生成冰柱):
char[,] array = new char[20, Console.BufferWidth];
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
if (i > 0 && array[i - 1, j] == ' ')
{
array[i, j] = ' ';
Console.Write(' ');
}
else
{
int x = getRandom.Next(10);
switch (x)
{
case 0:
array[i, j] = ' ';
Console.Write(array[i, j]);
break;
default:
array[i, j] = 'x';
Console.Write(array[i, j]);
break;
}
}
}
Console.WriteLine();
}