一段时间后全局键盘挂钩没有响应

发布于 2024-11-27 04:31:18 字数 2451 浏览 1 评论 0原文

我使用下面的代码,但几乎没有修改:

class globalKeyboardHook {

    public struct keyboardHookStruct {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);

    public keyboardHookProc hookP;

    const int WH_KEYBOARD_LL = 13;
    const int WM_KEYDOWN = 0x100;
    const int WM_KEYUP = 0x101;
    const int WM_SYSKEYDOWN = 0x104;
    const int WM_SYSKEYUP = 0x105;
    #endregion


    public List<Keys> HookedKeys = new List<Keys>();
    IntPtr hhook = IntPtr.Zero;


    public event KeyEventHandler KeyDown;

    public event KeyEventHandler KeyUp;


    public globalKeyboardHook() {
        hook();
    }


    ~globalKeyboardHook() {
        unhook();
    }



    public void hook() {
        IntPtr hInstance = LoadLibrary("User32");

        hookP = new keyboardHookProc(hookProc);

        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookP, hInstance, 0);
    }


    public void unhook() {
        UnhookWindowsHookEx(hhook);
    }

    public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) {
        if (code >= 0) {
            Keys key = (Keys)lParam.vkCode;
            if (HookedKeys.Contains(key)) {
                KeyEventArgs kea = new KeyEventArgs(key);
                if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) {
                    KeyDown(this, kea) ;
                } else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) {
                    KeyUp(this, kea);
                }
                if (kea.Handled)
                    return 1;
            }
        }
        return CallNextHookEx(hhook, code, wParam, ref lParam);
    }

    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    [DllImport("user32.dll")]
    static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

}

有时在几次按键后,“hookProc”不会被调用,就好像我已经“取消挂钩”事件一样,它根本不会捕获任何按键。除非我手动执行,否则如何确保它永远不会取消事件?我如何确保我继续订阅该挂钩?

谢谢。

I am using the code below but with little modification:

class globalKeyboardHook {

    public struct keyboardHookStruct {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);

    public keyboardHookProc hookP;

    const int WH_KEYBOARD_LL = 13;
    const int WM_KEYDOWN = 0x100;
    const int WM_KEYUP = 0x101;
    const int WM_SYSKEYDOWN = 0x104;
    const int WM_SYSKEYUP = 0x105;
    #endregion


    public List<Keys> HookedKeys = new List<Keys>();
    IntPtr hhook = IntPtr.Zero;


    public event KeyEventHandler KeyDown;

    public event KeyEventHandler KeyUp;


    public globalKeyboardHook() {
        hook();
    }


    ~globalKeyboardHook() {
        unhook();
    }



    public void hook() {
        IntPtr hInstance = LoadLibrary("User32");

        hookP = new keyboardHookProc(hookProc);

        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookP, hInstance, 0);
    }


    public void unhook() {
        UnhookWindowsHookEx(hhook);
    }

    public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) {
        if (code >= 0) {
            Keys key = (Keys)lParam.vkCode;
            if (HookedKeys.Contains(key)) {
                KeyEventArgs kea = new KeyEventArgs(key);
                if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) {
                    KeyDown(this, kea) ;
                } else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) {
                    KeyUp(this, kea);
                }
                if (kea.Handled)
                    return 1;
            }
        }
        return CallNextHookEx(hhook, code, wParam, ref lParam);
    }

    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    [DllImport("user32.dll")]
    static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

}

Sometimes after a few keypresses "hookProc" doesnt get called, as if i have "unhooked" the event, and it wont capture any keystrokes at all. How can i make sure that it never unhooks the event unless i do it in manually? How can i ensure that i keep subscribing to the hook?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文