Tim*_*Tim 11 c# user-input console-application
我有一个用C#编写的简单控制台应用程序.我希望能够检测箭头按键,这样我就可以让用户转向.如何使用控制台应用程序检测keydown/keyup事件?
我所有的谷歌搜索都导致了关于Windows窗体的信息.我没有GUI.这是一个控制台应用程序(通过串口控制机器人).
我有编写函数来处理这些事件,但我不知道如何注册以实际接收事件:
private void myKeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Left:
...
case Keys.Right:
...
case Keys.Up:
...
}
}
private void myKeyUp(object sender, KeyEventArgs e)
{
... pretty much the same as myKeyDown
}
Run Code Online (Sandbox Code Playgroud)
这可能是一个非常基本的问题,但我对C#还不熟悉,而且我以前从未需要这样的输入.
更新: 许多人建议我使用System.Console.ReadKey(true).Key.这没有用.我需要知道按键被释放的时刻,同时支持多个按键.此外,ReadKey是一个阻塞调用 - 这意味着程序将停止并等待按下一个键.
更新: 似乎唯一可行的方法是使用Windows窗体.这很烦人,因为我无法在无头系统上使用它.要求表单GUI接收键盘输入是......愚蠢的.
但无论如何,对于子孙后代,这是我的解决方案.我在.sln中创建了一个新的Form项目:
private void Form1_Load(object sender, EventArgs e)
{
try
{
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.KeyUp += new KeyEventHandler(Form1_KeyUp);
}
catch (Exception exc)
{
...
}
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
// handle up/down/left/right
case Keys.Up:
case Keys.Left:
case Keys.Right:
case Keys.Down:
default: return; // ignore other keys
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
// undo what was done by KeyDown
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您按住某个键,KeyDown将被多次调用,而KeyUp只会被调用一次(当您释放它时).所以你需要优雅地处理重复的KeyDown调用.
Erg*_*wun 15
现在有点晚了,但这里是如何在控制台应用程序中访问键盘状态.
请注意,它不是所有托管代码,因为它需要从User32.dll导入GetKeyState.
/// <summary>
/// Codes representing keyboard keys.
/// </summary>
/// <remarks>
/// Key code documentation:
/// http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx
/// </remarks>
internal enum KeyCode : int
{
/// <summary>
/// The left arrow key.
/// </summary>
Left = 0x25,
/// <summary>
/// The up arrow key.
/// </summary>
Up,
/// <summary>
/// The right arrow key.
/// </summary>
Right,
/// <summary>
/// The down arrow key.
/// </summary>
Down
}
/// <summary>
/// Provides keyboard access.
/// </summary>
internal static class NativeKeyboard
{
/// <summary>
/// A positional bit flag indicating the part of a key state denoting
/// key pressed.
/// </summary>
private const int KeyPressed = 0x8000;
/// <summary>
/// Returns a value indicating if a given key is pressed.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>
/// <c>true</c> if the key is pressed, otherwise <c>false</c>.
/// </returns>
public static bool IsKeyDown(KeyCode key)
{
return (GetKeyState((int)key) & KeyPressed) != 0;
}
/// <summary>
/// Gets the key state of a key.
/// </summary>
/// <param name="key">Virtuak-key code for key.</param>
/// <returns>The state of the key.</returns>
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern short GetKeyState(int key);
}
Run Code Online (Sandbox Code Playgroud)
var isUp = Console.ReadKey().Key == ConsoleKey.UpArrow;
Run Code Online (Sandbox Code Playgroud)
或另一个示例,仅针对您的情况:
while (true)
{
var ch = Console.ReadKey(false).Key;
switch(ch)
{
case ConsoleKey.Escape:
ShutdownRobot();
return;
case ConsoleKey.UpArrow:
MoveRobotUp();
break;
case ConsoleKey.DownArrow:
MoveRobotDown();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32441 次 |
| 最近记录: |