检测低级键盘挂钩中的特定键

时间:2014-12-06 16:29:39

标签: c# keyboard-hook

我正在创建一个应用程序,在系统托盘上放置一个图标,根据 Caps Lock 键的状态更改其外观。我面临的问题是,只有在按下Caps Lock之外的按键时钩子才能正常工作,因为该按键在钩子通过后翻转检查,使图标显示错误状态。

我需要一种方法来检测钩子内部何时按下Caps Lock键以翻转检测到的状态。

private static NotifyIcon notifyIcon = new NotifyIcon();
private static bool CapsPressed = Control.IsKeyLocked(Keys.CapsLock);
static Icon
    AppIcon = CapsIndicator.Properties.Resources.AppIcon,
    OnIcon =  CapsIndicator.Properties.Resources.OnIcon,
    OffIcon = CapsIndicator.Properties.Resources.OffIcon;

static void UpdateIcon() {
    notifyIcon.Icon = CapsPressed ? OnIcon : OffIcon;
}

// Hook initializing & other stuff here

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
    if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) {
        CapsPressed = Control.IsKeyLocked(Keys.CapsLock);
        UpdateIcon();
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

1 个答案:

答案 0 :(得分:1)

解决方案不是很直接,但可以使用lParam指针参数显示关键代码。您可以通过访问Marshal.ReadInt32指向的32位整数来执行此操作,然后,您需要将其转换为Keys类型,最后将此值与Keys.CapsLock进行比较(或你喜欢的任何其他钥匙):

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
    if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) {
        int vkCode = Marshal.ReadInt32(lParam);

        CapsPressed = Control.IsKeyLocked(Keys.CapsLock);
        // Flip the detected value if CapsLock is pressed
        if ((Keys) vkCode == Keys.CapsLock) CapsPressed = !CapsPressed;

        UpdateIcon();
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}