使用 KBDLLHOOKSTRUCT 确定第一次按键

问题描述 投票:0回答:2

我在 Windows 上使用低级键盘挂钩。尽管我目前无法判断该键是最初按下还是再次按下,但它的工作原理就像一个魅力。 documentation(+here)说,第 7 位保存过渡状态。但这似乎只有在释放钥匙时才是正确的。遗憾的是,当我第一次按下该键时,第 7 位并未设置。

有什么方法可以判断按键是否被按下?

windows winapi keyboard-hook
2个回答
1
投票

我最近碰巧遇到了这个问题。我找不到任何好的解决方案,但我最终在

GetAsyncKeyState
之前使用了一个标志和一个
SetWindowHookEx

BOOL wasDown;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        LPKBDLLHOOKSTRUCT key = (LPKBDLLHOOKSTRUCT) lParam;
        if (key->vkCode == VK_SOMETHING) {
            switch (wParam) {
                case WM_KEYDOWN:
                case WM_SYSKEYDOWN:
                    if (!wasDown) {
                        // Processing on first key down
                        wasDown = true;
                    }
                    break;
                case WM_KEYUP:
                case WM_SYSKEYUP:
                    // Processing on key up
                    wasDown = FALSE;
                    break;
            }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

wasDown = GetAsyncKeyState(VK_SOMETHING) < 0;
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);

当然,这段代码只对一个键起作用。您可以使用标志数组来执行多个键。根据您的应用程序,如果您希望在设置挂钩后第一次按下,您也可以无条件地将标志设置为

false


0
投票

我知道这是一个超级旧的线程,但由于还没有真正好的答案,所以这对我有用:

public static int LowLevelKeyboardProc(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam) {
    if (nCode >= 0) {
        Debug.Log(
            "Key: " + lParam.vkCode + 
            ", Is Down: " + (lParam.flags >> 7 == 0));
    }

    return 0;//CallNextHookEx( m_hhook, nCode, wParam, ref lParam);
}

根据 KBDLLHOOKSTRUCT 的文档关于变量标志:

LLKHF_UP (KF_UP >> 8) 测试过渡状态标志。

© www.soinside.com 2019 - 2024. All rights reserved.