我有一个控制台应用程序,提示用户输入多个输入。我希望用户能够在任何提示取消操作后按下转义。
类似的东西:
if (Console.ReadKey().Key != ConsoleKey.Escape) {
string input = Console.ReadLine();
...
}
然而,问题是,如果按下除了escape之外的键,它将不是输入的一部分(从ReadLine
返回)。
有没有办法“偷看”下一把钥匙,否则就这样做?
答案 0 :(得分:6)
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct InputRecord
{
internal short eventType;
internal KeyEventRecord keyEvent;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct KeyEventRecord
{
internal bool keyDown;
internal short repeatCount;
internal short virtualKeyCode;
internal short virtualScanCode;
internal char uChar;
internal int controlKeyState;
}
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool PeekConsoleInput(IntPtr hConsoleInput, out InputRecord buffer, int numInputRecords_UseOne, out int numEventsRead);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool ReadConsoleInput(IntPtr hConsoleInput, out InputRecord buffer, int numInputRecords_UseOne, out int numEventsRead);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle);
static Nullable<InputRecord> PeekConsoleEvent()
{
InputRecord ir;
int num;
if (!PeekConsoleInput(GetStdHandle(-10), out ir, 1, out num))
{
//TODO process error
}
if (num != 0)
return ir;
return null;
}
static InputRecord ReadConsoleInput()
{
InputRecord ir;
int num;
if (!ReadConsoleInput(GetStdHandle(-10), out ir, 1, out num))
{
//TODO process error
}
return ir;
}
static bool PeekEscapeKey()
{
for (; ; )
{
var ev = PeekConsoleEvent();
if (ev == null)
{
Thread.Sleep(10);
continue;
}
if (ev.Value.eventType == 1 && ev.Value.keyEvent.keyDown && ev.Value.keyEvent.virtualKeyCode == 27)
{
ReadConsoleInput();
return true;
}
if (ev.Value.eventType == 1 && ev.Value.keyEvent.keyDown)
return false;
ReadConsoleInput();
}
}
用法示例:
for (; ; )
{
Console.Write("?");
if (PeekEscapeKey())
{
Console.WriteLine("esc");
continue;
}
Console.Write(">");
var line = Console.ReadLine();
Console.WriteLine(line);
}
答案 1 :(得分:1)
要窥视,您必须使用TextReader.Peek。要在控制台中使用它,您可以使用Console.In.Peek()
。
要使用您正在考虑的代码:
if(Console.In.Peek() != "\0x1B") // 0x1B is the Escape Key
{
string input = Console.ReadLine();
....
}
这应该有效。我没有测试过,但似乎没错。
答案 2 :(得分:1)
或者用于比@ user823682
更不优雅的方法ConsoleKeyInfo key = Console.ReadKey().Key;
if (key != ConsoleKey.Escape) {
string input = String.Concat(key.KeyChar,Console.ReadLine());
...
}