Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class ConsoleEx
- {
- static object accessToken = new object(); // блокировка
- int currX, currY; // текущие координаты этого объекта
- static ConsoleEx focusOwner = null;
- public ConsoleEx(int startX, int startY)
- {
- currX = startX;
- currY = startY;
- }
- // эти два метода должны вызываться под блокировкой
- void SaveCursorPosition()
- {
- currX = Console.CursorLeft;
- currY = Console.CursorTop;
- }
- void RestoreCursorPosition()
- {
- Console.SetCursorPosition(currX, currY);
- }
- // в пустом конструкторе запоминаем текущие координаты
- public ConsoleEx()
- {
- lock (accessToken)
- SaveCursorPosition();
- }
- // вспомогательный метод: выполнить действие и запомнить обновлённую позицию курсора
- // если есть фокус, отдать курсор ему
- void Execute(Action a)
- {
- lock (accessToken)
- {
- RestoreCursorPosition();
- a();
- SaveCursorPosition();
- if (focusOwner != null && focusOwner != this)
- focusOwner.RestoreCursorPosition();
- }
- }
- // запись происходит очевидным образом
- public void Write(string s) => Execute(() => Console.Write(s));
- public void WriteLine(string s) => Execute(() => Console.WriteLine(s));
- // чтение сложнее, делаем посимвольно
- public string ReadLine()
- {
- ConsoleEx oldFocus = Focus();
- try
- {
- StringBuilder line = new StringBuilder();
- int startX = currX, startY = currY;
- while (true)
- {
- // читаем нажатие без отображения
- var key = Console.ReadKey(intercept: true);
- lock (accessToken)
- {
- // если фокус не наш, игнорируем
- if (focusOwner != null && focusOwner != this)
- continue;
- }
- // Enter -> заканчиваем ввод
- if (key.Key == ConsoleKey.Enter)
- {
- Execute(Console.WriteLine);
- return line.ToString();
- }
- // Backspace -> уничтожаем предыдущий символ
- else if (key.Key == ConsoleKey.Backspace)
- {
- if (line.Length == 0)
- continue;
- lock (accessToken)
- {
- line[line.Length - 1] = ' ';
- Console.SetCursorPosition(startX, startY);
- Console.Write(line.ToString());
- line.Length--;
- Console.SetCursorPosition(startX, startY);
- Console.Write(line.ToString());
- SaveCursorPosition();
- }
- }
- // остальные символы выводим как есть
- else
- {
- line.Append(key.KeyChar);
- Execute(() => Console.Write(key.KeyChar));
- }
- }
- }
- finally
- {
- SetFocus(oldFocus);
- }
- }
- public ConsoleEx Focus() => SetFocus(this);
- public void Unfocus() => SetFocus(null);
- public static ConsoleEx SetFocus(ConsoleEx k)
- {
- lock (accessToken)
- {
- var oldFocusOwner = focusOwner;
- focusOwner = k;
- focusOwner?.RestoreCursorPosition();
- return oldFocusOwner;
- }
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- ConsoleEx kin = new ConsoleEx(0, 0);
- Task.Run(async () =>
- {
- ConsoleEx kout = new ConsoleEx(0, 10);
- for (int i = 0; i < 100; i++)
- {
- await Task.Delay(1000);
- kout.Write($"{i} ");
- }
- });
- var result = kin.ReadLine();
- kin.WriteLine($"You entered: {result}");
- kin.WriteLine("Press any key");
- Console.ReadKey(intercept: true);
- }
- }
Add Comment
Please, Sign In to add comment