【问题标题】:Display all keys combination显示所有组合键
【发布时间】:2014-10-07 20:04:06
【问题描述】:

我编写了以下一段代码来显示所有击键。我想知道的是,如果我按 Ctrl+AAlt+O 等组合键>Ctrl+DeleteCtrl+Alt+Delete 这些键也会显示在控制台上。应该怎么做?

另一件突然想到的事情是,如果有人按住一个键并继续按下另一个键,如何在这里捕捉到这种行为?

[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Int32 i);

for (Int32 i = 0; i < 255; i++)
{
    int keyState = GetAsyncKeyState(i);
    if (keyState == 1 || keyState == -32767)
    {
        Console.WriteLine((Keys)i);
        break;
    }
}

【问题讨论】:

  • 是的,我读到了,但对于像我这样的傻瓜来说这很神秘。实际上,win32 API 对我来说看起来很可怕。我计划一遍又一遍地阅读,然后决定把我的代码扔到垃圾中,但后来我认为有 stackoverflow 可以帮助我。
  • @khan,那么你必须培养理解文档所需的背景和技能,否则你没有机会理解实际代码的作用。
  • 我不确定您要做什么?您是否尝试从后台应用程序读取键盘状态?
  • @Black Frog 不,只是一个控制台应用程序。

标签: c# .net keyboard console-application


【解决方案1】:

我相信您正在寻找GetKeyboardState 功能。我将在一次通话中为您提供所有虚拟键的状态。 GetAsyncKeyState 函数更适合用于检查用户是否按下了某个键。

作为练习,我编写了以下代码来演示 GetAsyncKeyState API 调用:

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace s26244308
{
    class Program
    {
        static void Main(string[] args)
        {
            bool keepGoing = true;

            while (keepGoing)
            {
                int wasItPressed = SysWin32.GetAsyncKeyState(SysWin32.VK_ESCAPE);
                if (wasItPressed != 0)
                {
                    keepGoing = false;  // stop
                    continue;
                }

                // for this sample: just loop a few letters
                for (int x = 0x41; x <= 0x4A; x++)
                {
                    int letterPressed = SysWin32.GetAsyncKeyState(x);
                    if (letterPressed != 0)
                    {
                        // now check for a few other keys
                        int shiftAction = SysWin32.GetAsyncKeyState(SysWin32.VK_SHIFT);
                        int ctrlAction = SysWin32.GetAsyncKeyState(SysWin32.VK_CONTROL);
                        int altAction = SysWin32.GetAsyncKeyState(SysWin32.VK_MENU);

                        // format my output
                        string letter = string.Format("Letter: {0} ({1})", Convert.ToChar(x), KeyAction(letterPressed));
                        string shift = string.Format("Shift: {0}", KeyAction(shiftAction));
                        string ctrl = string.Format("Control: {0}", KeyAction(ctrlAction));
                        string alt = string.Format("Alt: {0}", KeyAction(altAction));

                        Console.WriteLine("{0,-20}{1,-18}{2,-18}{3,-18}", letter, shift, ctrl, alt);
                        break;
                    }
                }
                Thread.Sleep(10);
            }

            Console.WriteLine("-- Press Any Key to Continue --");
            Console.ReadLine();
        }

        private static string KeyAction(int pressed)
        {
            if (pressed == 0)
                return "Up";

            // check LSB
            if (IsBitSet(pressed, 0))
                return "Pressed";

            // checked MSB
            if (IsBitSet(pressed, 15))
                return "Down";

            return Convert.ToString(pressed, 2);
        }
        private static bool IsBitSet(int b, int pos)
        {
            return (b & (1 << pos)) != 0;
        }
    }

    class SysWin32
    {
        public const int VK_ESCAPE = 0x1B;
        public const int VK_SHIFT = 0x10;
        public const int VK_CONTROL = 0x11;
        public const int VK_MENU = 0x12;

        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Int32 i);
    }

}

这是控制台输出:

【讨论】:

  • 感谢您为我做这个练习。
  • 一件让我恼火的事情是为什么我们需要一个 getAsync 循环,因为它接受键盘输入,我的意思是它如何在 for 循环的特定迭代中正确显示我的输入键。
  • 因为线程休眠了。如果在线程休眠时按下某个键,线程只能告诉你之后的动作。而且你不能让线程一直在听。这听起来更像是您需要连接到 Windows 消息泵来获取所有键盘消息。查看来自C++ console keyboard events 的已接受答案。
【解决方案2】:

我想我明白你在问什么。您需要一种方法来检查用户按下的组合键。我已经尝试了您正在寻找的内容,但没有使用 GetAsyncKeyState()。

这是我所做的 KeyDown 事件操作:

prevKey = currentKey;
currentKey = e.KeyCode; 

if (prevKey == Keys.ControlKey && currentKey == Keys.Menu)
{
   // Some action
}
else
   // Some other action

您可以监控用户按下的组合键并将操作与特定组合相关联。上面的代码显示了用户是否按该顺序按 CTRL + ALT。

KeyDown 事件更好的原因是因为您在按下时立即捕获键值。

【讨论】:

    猜你喜欢
    • 2019-07-23
    • 2020-05-20
    • 1970-01-01
    • 2019-11-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    相关资源
    最近更新 更多