Reputation: 29
I know how to set the cursor to a specific point in the console with SetCursorPosition or CursorLeft and CursorTop together. That's not a problem.
But, how can I get the value of that point? Isn't there a thing like Console.Cursor? So I can get the character at that position? Maybe something like:
char c = Console.GetCharAtCursor();
No luck?
Upvotes: 2
Views: 5525
Reputation: 422
I did not like the long answers posted here for my simple application, so I figured a workaround for this – I stored the entire console buffer in a 2D array and then just indexed in the array. Worked for my application (generating icicles in console):
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();
}
Upvotes: 0
Reputation: 122
According the answer from the MSDN forum:
[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';
}
}
Applied it looks like this:
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();
}
}
Upvotes: 0
Reputation: 52420
AFAIK, you have to read the entire console buffer as a two dimensional buffer, and use the cursor's X and Y coordinates as an index into that buffer. See:
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool GetConsoleScreenBufferInfo(
IntPtr consoleHandle,
out CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo);
You can read about the buffer structure here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
Update:
If you're interested in using console APIs for game writing, someone wrote space invaders for the console (actually powershell) but all of the APIs are managed code, not script. He has sprite/path routines etc - the source is over on http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/
Upvotes: 6
Reputation: 12226
'CursorLeft' and 'CursorTop' have getters so you can just read them: var cleft = Console.CursorLeft
Upvotes: 0