显示所有组合键

Posted

技术标签:

【中文标题】显示所有组合键【英文标题】: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;
    

【问题讨论】:

你read the documentation for GetAsyncKeyState了吗? 是的,我读到了,但对于像我这样的傻瓜来说这很神秘。实际上,win32 API 对我来说看起来很可怕。我计划一遍又一遍地阅读,然后决定把我的代码扔到垃圾中,但后来我认为有 *** 可以帮助我。 @khan,那么你必须培养理解文档所需的背景和技能,否则你没有机会理解实际代码的作用。 我不确定您要做什么?您是否尝试从后台应用程序读取键盘状态? @Black Frog 不,只是一个控制台应用程序。 【参考方案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,-201,-182,-183,-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 事件更好的原因是因为您在按下时立即捕获键值。

【讨论】:

以上是关于显示所有组合键的主要内容,如果未能解决你的问题,请参考以下文章

将字典中具有相同值的所有键组合在一起,并将键与值交换,将值与键交换

Win+Break”组合键 怎么打?

vc中应该如何向窗口发送组合键消息

在 MS-Access 中,当外键不再存在时,如何在组合框中显示旧的外键?

哈希函数和组合多个键

按下组合键时聚焦用户控件的子控件