【问题标题】:C# Actively detect Lock keysC#主动检测锁键
【发布时间】:2013-07-16 17:50:30
【问题描述】:

我有一个没有任何锁定指示灯的无线键盘和鼠标,也没有捆绑任何提供视觉辅助的软件,所以我自己制作。

我知道了,如果我点击一个 notifyIcon,它会列出打开了哪些锁,但我想通过在锁被使用时提醒我来让它更智能。

我在网上找到了一些东西,但老实说我只想要锁定键,我不在乎任何其他键盘按键。

我使用的是 C# .NET 4,但如果该版本有某些内容,我可以使用 .NET 4.5。

谢谢。

【问题讨论】:

    标签: c# keyboard-events notifyicon


    【解决方案1】:

    您需要注册某种键盘挂钩来监听按键,然后检索锁定键的状态,如下所示:
    http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

    除了上述文章之外,进行以下修改以捕获锁定键的状态:

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Keys key = (Keys)vkCode;
            if (key == Keys.Capital)
            {
                Console.WriteLine("Caps Lock: " + !Control.IsKeyLocked(Keys.CapsLock)); 
            }
            if (key == Keys.NumLock)
            {
                Console.WriteLine("NumLock: " + !Control.IsKeyLocked(Keys.NumLock));
            }
            if (key == Keys.Scroll)
            {
                Console.WriteLine("Scroll Lock: " + !Control.IsKeyLocked(Keys.Scroll));
            }
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }
    

    【讨论】:

    • 我如何将它用作非控制台应用程序?
    • 在每个if 语句中,您可以通过使用NotifyIcon 控件显示一个气球提示来显示键盘状态更改。 msdn.microsoft.com/en-us/library/…
    • 不要再推荐 Toub 文章了,它有一个 critical bug 阻止它在 .NET 4 中工作。
    • 感谢大家的帮助,这个解决方案帮助我让应用程序按我想要的方式工作。
    【解决方案2】:

    这是一个截取表单或其他东西上的keyup并跟踪它的示例。我更改了一个局部变量,但此时您可以轻松触发 GUI 更新。

        private bool capLock;
        private bool numLock;
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.CapsLock)
            {
                capLock = !capLock;
            }
            if (e.KeyCode == Keys.NumLock)
            {
                numLock = !numLock;
            }
        }
    

    【讨论】:

      【解决方案3】:

      查看以下有关全局键盘事件的文章。当按下其中一个锁定键时,您可以更新您的 UI...

      http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

      【讨论】:

      【解决方案4】:

      您可以使用Control.IsKeyLocked(...) 方法,如下所述:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.iskeylocked%28v=vs.100%29.aspx

      该方法从 .NET 2.0 开始可用,可以这样使用:

      bool capsLock = Control.IsKeyLocked(Keys.CapsLock);
      bool numLock = Control.IsKeyLocked(Keys.NumLock);
      bool scrollLock = Control.IsKeyLocked(Keys.Scroll);
      

      此解决方案不需要导入 WinApi 函数或手动跟踪按键状态。

      更新

      为了跟踪锁定键的变化,我建议您尝试以下解决方案之一:

      • 添加一个全局挂钩来捕获所有按键,然后检查按下的键是否是锁定键之一。但是,这将使您的钩子在每次按下任何键时都运行。您可以在此处找到有关键盘键全局挂钩的更多信息:http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
      • 您还可以实现一个不时执行的计时器,检查按键状态并通知用户,如果其中任何一个状态发生了变化。如果您不经常运行计时器,它应该不会占用太多资源。

      【讨论】:

      • 我已经在使用那个方法了,问题是如何在没有任何额外交互的情况下通知用户。
      • 我想如果你想捕捉所有按键,你必须添加一个全局钩子,即使你的应用程序当前不在前台。看看这个以获取更多信息:blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx.
      猜你喜欢
      • 2012-06-24
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多