【问题标题】:Wait for key to be released等待密钥被释放
【发布时间】:2019-03-25 00:18:55
【问题描述】:

在我制作的一个简单测试程序中,您可以使用Console.ReadKey() 递增一个值。但是,您可以按住按钮,它只会不断增加值。我希望我的程序等待密钥被释放,这样你就无法持有密钥。我该怎么做?

【问题讨论】:

    标签: c# console


    【解决方案1】:

    尝试使用 Control.keyPress() 事件而不是 ReadKey()。

    这里有一些例子和参考

    https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.keypress?view=netframework-4.7.2

    【讨论】:

    【解决方案2】:

    我认为您需要使用键盘挂钩。 使用一个类,就像在 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();
    }
    

    【讨论】:

      【解决方案3】:

      你可以在这里使用GetKeyState函数。

      1. 让我们使用这个答案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);
            }
        }
        
        }
      2. 包装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;
        }
      3. 测试方法。

        static void Main(string[] args)
        {
            int i = 0;
            while (true)
            {
                var key = ReadKey();
                if (key == ConsoleKey.UpArrow)
                {
                    Console.WriteLine(++i);
                }
            }
        }

      【讨论】:

        猜你喜欢
        • 2015-01-25
        • 1970-01-01
        • 2010-11-27
        • 2019-08-24
        • 1970-01-01
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        • 2021-11-12
        相关资源
        最近更新 更多