【发布时间】:2019-03-25 00:18:55
【问题描述】:
在我制作的一个简单测试程序中,您可以使用Console.ReadKey() 递增一个值。但是,您可以按住按钮,它只会不断增加值。我希望我的程序等待密钥被释放,这样你就无法持有密钥。我该怎么做?
【问题讨论】:
在我制作的一个简单测试程序中,您可以使用Console.ReadKey() 递增一个值。但是,您可以按住按钮,它只会不断增加值。我希望我的程序等待密钥被释放,这样你就无法持有密钥。我该怎么做?
【问题讨论】:
尝试使用 Control.keyPress() 事件而不是 ReadKey()。
这里有一些例子和参考
【讨论】:
我认为您需要使用键盘挂钩。 使用一个类,就像在 https://social.msdn.microsoft.com/Forums/vstudio/en-US/88ae8842-5301-4b15-830e-1d6282303508/how-to-listen-to-keyboard-inputs?forum=netfxbcl
这个类是一个全局键盘钩子处理程序。 在处理程序方法“OnHookCallback”中做任何你想做的事情。它确实喜欢 ReadKey() 方法。你可以读取按下的键,写下键的值,或者做任何你想做的事情。此外,您可以检测到此键事件是 KeyDown 或 KeyUp。 因此拼图完成。您拥有键值,并且您知道按键按下和按键向上事件。因此,您可以将按下时的键值与释放时的值进行比较。例如,如果您有 5 次 KeyDown 事件上升而没有任何 KeyUp 事件,则表示该键已被按住并已保留一段时间。因此,在这种情况下,您可以避免计数器的增加。
但是,您使用的是控制台应用程序,因此您需要按照C# global keyboard hook, that opens a form from a console application 中的说明更改 main 方法
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
LowLevelKeyboardHook kbh = new LowLevelKeyboardHook();
kbh.OnKeyPressed += kbh_OnKeyPressed;
kbh.OnKeyUnpressed += kbh_OnKeyUnpressed;
kbh.HookKeyboard();
Application.Run();
kbh.UnHookKeyboard();
}
【讨论】:
你可以在这里使用GetKeyState函数。
让我们使用这个答案https://stackoverflow.com/a/9356006/4631959中的修改代码
我们将使用ConsoleKey 而不是Key,因为我们在这里不使用WinForms。
using System;
using System.Runtime.InteropServices;
namespace NetFramework
{
public static class Keyboard
{
[Flags]
private enum KeyStates
{
None = 0,
Down = 1,
Toggled = 2
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern short GetKeyState(int keyCode);
private static KeyStates GetKeyState(ConsoleKey key)
{
KeyStates state = KeyStates.None;
short retVal = GetKeyState((int)key);
//If the high-order bit is 1, the key is down
//otherwise, it is up.
if ((retVal & 0x8000) == 0x8000)
state |= KeyStates.Down;
//If the low-order bit is 1, the key is toggled.
if ((retVal & 1) == 1)
state |= KeyStates.Toggled;
return state;
}
public static bool IsKeyDown(ConsoleKey key)
{
return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
}
public static bool IsKeyToggled(ConsoleKey key)
{
return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
}
}
}
包装Console.ReadKey() 方法。
此方法只有在您释放按钮时才会返回键。
static ConsoleKey ReadKey()
{
var key = Console.ReadKey().Key;
//wait while key is pressed
while (Keyboard.IsKeyDown(key))
{
}
//flush input stream
while (Console.KeyAvailable)
Console.ReadKey(true);
return key;
}
测试方法。
static void Main(string[] args)
{
int i = 0;
while (true)
{
var key = ReadKey();
if (key == ConsoleKey.UpArrow)
{
Console.WriteLine(++i);
}
}
}
【讨论】: