глобальный хук клавиатуры не отвечает через некоторое время - PullRequest
1 голос
/ 01 августа 2011

Я использую код ниже, но с небольшими изменениями:

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» не вызывается, как будто я «отцепил» событие, и оно вообще не будет захватывать нажатие клавиш. Как я могу убедиться, что оно никогда не отцепит событие, если я не сделаю это вручную? Как я могу гарантировать, что я продолжаю подписываться на крючок?

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...