예제 #1
0
파일: KeyHook.cs 프로젝트: clks2001/csharp
        private List <Keys> _preKeysList = new List <Keys>();//存放被按下的控制键,用来生成具体的键

        private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)
        {
            //如果该消息被丢弃(nCode<0)或者没有事件绑定处理程序则不会触发事件
            if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
            {
                var keyDataFromHook = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                var keyData         = (Keys)keyDataFromHook.vkCode;
                //按下控制键
                if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WmKeydown || wParam == WmSyskeydown))
                {
                    if (IsCtrlAltShiftKeys(keyData) && _preKeysList.IndexOf(keyData) == -1)
                    {
                        _preKeysList.Add(keyData);
                    }
                }
                //WM_KEYDOWN和WM_SYSKEYDOWN消息,将会引发OnKeyDownEvent事件
                if (OnKeyDownEvent != null && (wParam == WmKeydown || wParam == WmSyskeydown))
                {
                    var e = new KeyEventArgs(GetDownKeys(keyData));

                    OnKeyDownEvent?.Invoke(this, e);
                }
                //WM_KEYDOWN消息将引发OnKeyPressEvent
                if (OnKeyPressEvent != null && wParam == WmKeydown)
                {
                    var keyState = new byte[256];
                    GetKeyboardState(keyState);
                    var inBuffer = new byte[2];
                    if (ToAscii(keyDataFromHook.vkCode, keyDataFromHook.scanCode, keyState, inBuffer, keyDataFromHook.flags) == 1)
                    {
                        var e = new KeyPressEventArgs((char)inBuffer[0]);
                        OnKeyPressEvent(this, e);
                    }
                }
                //松开控制键
                if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WmKeyup || wParam == WmSyskeyup))
                {
                    if (IsCtrlAltShiftKeys(keyData))
                    {
                        for (var i = _preKeysList.Count - 1; i >= 0; i--)
                        {
                            if (_preKeysList[i] == keyData)
                            {
                                _preKeysList.RemoveAt(i);
                            }
                        }
                    }
                }
                //WM_KEYUP和WM_SYSKEYUP消息,将引发OnKeyUpEvent事件
                if (OnKeyUpEvent != null && (wParam == WmKeyup || wParam == WmSyskeyup))
                {
                    var e = new KeyEventArgs(GetDownKeys(keyData));
                    OnKeyUpEvent?.Invoke(this, e);
                }
            }
            return(CallNextHookEx(_hHook, nCode, wParam, lParam));
        }
        private static IntPtr HookCallbackMouse(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                // read hiword from mouseData field in MSLLHOOKSTRUCT
                var mouseKey = Marshal.ReadInt32(lParam + 8) >> 16;

                switch ((int)wParam)
                {
                case WM_XBUTTONDOWN:
                    OnKeyDownEvent?.Invoke(XButtonToVK(mouseKey));
                    break;

                case WM_XBUTTONUP:
                    OnKeyUpEvent?.Invoke(XButtonToVK(mouseKey));
                    break;

                default:
                    break;
                }
            }

            return(CallNextHookEx(hookIdMouse, nCode, wParam, lParam));
        }
        private static IntPtr HookCallbackKeyboard(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                // keycode is at start of lParam struct so just read an int32
                var key = Marshal.ReadInt32(lParam);

                switch ((int)wParam)
                {
                case WM_KEYDOWN:
                    OnKeyDownEvent?.Invoke(key);
                    break;

                case WM_KEYUP:
                    OnKeyUpEvent?.Invoke(key);
                    break;

                default:
                    break;
                }
            }

            return(CallNextHookEx(hookIdKeyboard, nCode, wParam, lParam));
        }
예제 #4
0
        private static IntPtr KbLLHookCallback(int nCode, HOOKPROC wParam, TagKBDLLHOOKSTRUCT lParam)
        {
            KeyboardEventArgs EvtArgs = new KeyboardEventArgs();

            EvtArgs.LowLevelKbInfo.dwExtraInfo = lParam.dwExtraInfo;
            EvtArgs.LowLevelKbInfo.flags       = lParam.flags;
            EvtArgs.LowLevelKbInfo.scanCode    = lParam.scanCode;
            EvtArgs.LowLevelKbInfo.time        = lParam.time;
            EvtArgs.LowLevelKbInfo.vkCode      = lParam.vkCode;
            if (nCode >= 0 && (wParam == HOOKPROC.WM_KEYDOWN || wParam == HOOKPROC.WM_SYSKEYDOWN) && lParam.flags == KBDLLHOOKSTRUCTFlags.LLKHF_EXTENDED)
            {
                if (lParam.vkCode.Equals(VK_KEY_CODE.VK_SHIFT) || lParam.vkCode.Equals(VK_KEY_CODE.VK_LSHIFT) || lParam.vkCode.Equals(VK_KEY_CODE.VK_RSHIFT))
                {
                    SHIFT_KEY_DOWN = true;
                }
            }
            if (nCode >= 0 && (wParam == HOOKPROC.WM_KEYDOWN || wParam == HOOKPROC.WM_SYSKEYDOWN))
            {
                CAPS_LOCK_ON = GetKeyState(0x14) != 0 || System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock);
                NumLock      = GetKeyState(0x90) != 0;
                ScrollLock   = GetKeyState(0x91) != 0;
                VK_CHAR      = '\u0000';
                OnKeyDownEvent?.Invoke(nCode, EvtArgs);
                switch (lParam.vkCode)
                {
                case VK_KEY_CODE.VK_LWIN:
                    WIN_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_RWIN:
                    WIN_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_CAPITAL:
                    break;

                case VK_KEY_CODE.VK_MENU:
                    ALT_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_LMENU:
                    ALT_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_RMENU:
                    ALTGR_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_SHIFT:
                    SHIFT_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_RSHIFT:
                    SHIFT_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_LSHIFT:
                    SHIFT_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_CONTROL:
                    CTRL_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_LCONTROL:
                    CTRL_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_RCONTROL:
                    CTRL_KEY_DOWN = true;
                    break;

                case VK_KEY_CODE.VK_SPACE:
                    strBuilder.Append(" ");
                    break;

                case VK_KEY_CODE.VK_RETURN:
                    strBuilder.AppendLine();
                    break;

                case VK_KEY_CODE.VK_BACK:
                    break;

                case VK_KEY_CODE.VK_0:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u003D' : '\u0030';
                    VK_CHAR = '\u0030';
                    break;

                case VK_KEY_CODE.VK_1:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0021' : '\u0031';
                    VK_CHAR = '\u0031';
                    break;

                case VK_KEY_CODE.VK_2:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0022' : '\u0032';
                    VK_CHAR = '\u0032';
                    break;

                case VK_KEY_CODE.VK_3:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0023' : '\u0033';
                    VK_CHAR = '\u0033';
                    break;

                case VK_KEY_CODE.VK_4:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0024' : '\u0034';
                    VK_CHAR = '\u0034';
                    break;

                case VK_KEY_CODE.VK_5:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0025' : '\u0035';
                    VK_CHAR = '\u0035';
                    break;

                case VK_KEY_CODE.VK_6:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0026' : '\u0036';
                    VK_CHAR = '\u0036';
                    break;

                case VK_KEY_CODE.VK_7:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u002F' : '\u0037';
                    VK_CHAR = '\u0037';
                    break;

                case VK_KEY_CODE.VK_8:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0028' : '\u0038';
                    VK_CHAR = '\u0038';
                    break;

                case VK_KEY_CODE.VK_9:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u0029' : '\u0039';
                    VK_CHAR = '\u0039';
                    break;

                case VK_KEY_CODE.VK_A:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0041' : '\u0061';
                    break;

                case VK_KEY_CODE.VK_B:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0042' : '\u0062';
                    break;

                case VK_KEY_CODE.VK_C:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0043' : '\u0063';
                    break;

                case VK_KEY_CODE.VK_D:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0044' : '\u0064';
                    break;

                case VK_KEY_CODE.VK_E:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0045' : '\u0065';
                    break;

                case VK_KEY_CODE.VK_F:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0046' : '\u0066';
                    break;

                case VK_KEY_CODE.VK_G:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0047' : '\u0067';
                    break;

                case VK_KEY_CODE.VK_H:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0048' : '\u0068';
                    break;

                case VK_KEY_CODE.VK_I:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0049' : '\u0069';
                    break;

                case VK_KEY_CODE.VK_J:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004A' : '\u006A';
                    break;

                case VK_KEY_CODE.VK_K:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004B' : '\u006B';
                    break;

                case VK_KEY_CODE.VK_L:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004C' : '\u006C';
                    break;

                case VK_KEY_CODE.VK_M:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004D' : '\u006D';
                    break;

                case VK_KEY_CODE.VK_N:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004E' : '\u006E';
                    break;

                case VK_KEY_CODE.VK_O:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u004F' : '\u006F';
                    break;

                case VK_KEY_CODE.VK_P:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0050' : '\u0070';
                    break;

                case VK_KEY_CODE.VK_Q:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0051' : '\u0071';
                    break;

                case VK_KEY_CODE.VK_R:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0052' : '\u0072';
                    break;

                case VK_KEY_CODE.VK_S:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0053' : '\u0073';
                    break;

                case VK_KEY_CODE.VK_T:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0054' : '\u0074';
                    break;

                case VK_KEY_CODE.VK_U:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0055' : '\u0075';
                    break;

                case VK_KEY_CODE.VK_V:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0056' : '\u0076';
                    break;

                case VK_KEY_CODE.VK_W:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0057' : '\u0077';
                    break;

                case VK_KEY_CODE.VK_X:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0058' : '\u0078';
                    break;

                case VK_KEY_CODE.VK_Y:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u0059' : '\u0079';
                    break;

                case VK_KEY_CODE.VK_Z:
                    VK_CHAR = (CAPS_LOCK_ON || SHIFT_KEY_DOWN) ? '\u005A' : '\u007A';
                    break;

                case VK_KEY_CODE.VK_OEM_3:
                    if (KbLayoutName.ToLower().Equals("spanish") || KbLayoutName.ToLower().Equals("español") ||
                        KbLayoutName.ToLower().Equals("latin american") || KbLayoutName.ToLower().Equals("america latina"))
                    {
                        VK_CHAR = CAPS_LOCK_ON ? '\u00D1' : '\u00F1';
                    }
                    // char ñ or Ñ: For the US standard keyboard, the '`~' key
                    break;

                case VK_KEY_CODE.VK_OEM_7:
                    // For the US standard keyboard, the 'single-quote/double-quote' key
                    break;

                case VK_KEY_CODE.VK_OEM_2:
                    // For the US standard keyboard, the '/?' key
                    break;

                case VK_KEY_CODE.VK_OEM_1:
                    break;

                case VK_KEY_CODE.VK_OEM_4:
                    break;

                case VK_KEY_CODE.VK_OEM_6:
                    break;

                case VK_KEY_CODE.VK_OEM_5:
                    break;

                case VK_KEY_CODE.VK_OEM_PERIOD:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u003A' : '\u002E';
                    break;

                case VK_KEY_CODE.VK_OEM_COMMA:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u003B' : '\u002C';
                    break;

                case VK_KEY_CODE.VK_OEM_MINUS:
                    //VK_CHAR = SHIFT_KEY_DOWN ? '\u005F' : '\u002D';
                    break;

                case VK_KEY_CODE.VK_OEM_PLUS:
                    //if (SHIFT_KEY_DOWN) VK_CHAR = '\u002A';
                    //else VK_CHAR = '\u002B';
                    //if (ALTGR_KEY_DOWN) VK_CHAR = '\u007E';
                    break;

                default:
                    break;
                }

                if (!WIN_KEY_DOWN && VK_CHAR != '\u0000' && ALTGR_KEY_DOWN && (lParam.vkCode >= VK_KEY_CODE.VK_0) && (lParam.vkCode <= VK_KEY_CODE.VK_9))
                {
                    timer.Stop();
                    strBuilder.Append("{ALTGR:" + Convert.ToString(VK_CHAR).ToLower() + "}");
                    timer.Start();
                }
                else if (!WIN_KEY_DOWN && VK_CHAR != '\u0000' && SHIFT_KEY_DOWN && (lParam.vkCode >= VK_KEY_CODE.VK_0) && (lParam.vkCode <= VK_KEY_CODE.VK_9))
                {
                    timer.Stop();
                    strBuilder.Append("{SHIFT:" + Convert.ToString(VK_CHAR).ToLower() + "}");
                    timer.Start();
                }
                else if (!WIN_KEY_DOWN && VK_CHAR != '\u0000' && ALTGR_KEY_DOWN && ((int)lParam.vkCode >= 41) && ((int)lParam.vkCode <= 80))
                {
                    timer.Stop();
                    strBuilder.Append("{ALTGR:" + Convert.ToString(VK_CHAR) + "}");
                    timer.Start();
                }
                else if (!WIN_KEY_DOWN && VK_CHAR != '\u0000' && SHIFT_KEY_DOWN && ((int)lParam.vkCode >= 41) && ((int)lParam.vkCode <= 80))
                {
                    timer.Stop();
                    if (CAPS_LOCK_ON)
                    {
                        strBuilder.Append("{SHIFT:" + Convert.ToString(VK_CHAR).ToLower() + "}");
                    }
                    else
                    {
                        strBuilder.Append("{SHIFT:" + Convert.ToString(VK_CHAR) + "}");
                    }
                    timer.Start();
                }
                else if (!WIN_KEY_DOWN && VK_CHAR != '\u0000' && (!CAPS_LOCK_ON && SHIFT_KEY_DOWN || CAPS_LOCK_ON && !SHIFT_KEY_DOWN))
                {
                    timer.Stop();
                    timer.AutoReset = true;
                    //Trace(char.ConvertFromUtf32(VK_CHAR));
                    Trace(Convert.ToString(VK_CHAR).ToUpper());
                    strBuilder.Append(Convert.ToString(VK_CHAR).ToUpper());

                    timer.Start();
                }
                else if (!WIN_KEY_DOWN && VK_CHAR != '\u0000')
                {
                    timer.Stop();
                    //Trace(char.ConvertFromUtf32(VK_CHAR));
                    Trace(Convert.ToString(VK_CHAR).ToLower());
                    strBuilder.Append(Convert.ToString(VK_CHAR).ToLower());
                    timer.Start();
                }
            }

            if (nCode >= 0 && (wParam == HOOKPROC.WM_KEYUP || wParam == HOOKPROC.WM_SYSKEYUP))
            {
                OnKeyUpEvent?.Invoke(nCode, EvtArgs);
                switch (lParam.vkCode)
                {
                case VK_KEY_CODE.VK_LWIN:
                    WIN_KEY_DOWN = false;
                    break;

                case VK_KEY_CODE.VK_RWIN:
                    WIN_KEY_DOWN = false;
                    break;

                case VK_KEY_CODE.VK_LSHIFT:
                    SHIFT_KEY_DOWN = false;
                    break;

                case VK_KEY_CODE.VK_RSHIFT:
                    SHIFT_KEY_DOWN = false;
                    break;

                case VK_KEY_CODE.VK_RMENU:
                    ALTGR_KEY_DOWN = false;
                    break;

                case VK_KEY_CODE.VK_BACK:
                    strBuilder.Append("{DEL}");
                    break;
                }
            }
            return(CallNextHookEx(_LowLevelKbHookID, nCode, wParam, lParam));
        }
예제 #5
0
        private int KeyboardHookMethod(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                var param = Marshal.PtrToStructure <KeyboardLL>(lParam);
                //当有OnKeyDownEvent 或 OnKeyPressEvent 不为null时,ctrl alt shift keyup时 preKeys
                //中的对应的键增加
                if (wParam == WM_KeyDown || wParam == WM_SysKeyDown)
                {
                    Keys keyData = (Keys)param.vkCode;
                    if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)
                    {
                        preKeys.Add(keyData);
                    }
                }
                //引发OnKeyDownEvent
                if (wParam == WM_KeyDown || wParam == WM_SysKeyDown)
                {
                    Keys         keyData = (Keys)param.vkCode;
                    KeyEventArgs e       = new KeyEventArgs(GetDownKeys(keyData));

                    OnKeyDownEvent?.Invoke(this, e);
                }

                //引发OnKeyPressEvent
                if (wParam == WM_KeyDown)
                {
                    byte[] keyState = new byte[256];
                    Win32.GetKeyboardState(keyState);

                    byte[] inBuffer = new byte[2];
                    if (Win32.ToAscii(param.vkCode,
                                      param.scanCode,
                                      keyState,
                                      inBuffer,
                                      param.flags) == 1)
                    {
                        KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                        OnKeyPressEvent?.Invoke(this, e);
                    }
                }

                //当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
                //中的对应的键删除
                if (wParam == WM_KeyUp || wParam == WM_SysKeyUp)
                {
                    Keys keyData = (Keys)param.vkCode;
                    if (IsCtrlAltShiftKeys(keyData))
                    {
                        for (int i = preKeys.Count - 1; i >= 0; i--)
                        {
                            if (preKeys[i] == keyData)
                            {
                                preKeys.RemoveAt(i);
                            }
                        }
                    }
                }
                //引发OnKeyUpEvent
                if (wParam == WM_KeyUp || wParam == WM_SysKeyUp)
                {
                    Keys         keyData = (Keys)param.vkCode;
                    KeyEventArgs e       = new KeyEventArgs(GetDownKeys(keyData));
                    OnKeyUpEvent?.Invoke(this, e);
                }
            }
            return(Win32.CallNextHookEx(IdHook.KeyboardLL, nCode, wParam, lParam));
        }
예제 #6
0
        private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)

        {
            if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))

            {
                Win32Api.KeyboardHookStruct KeyDataFromHook =
                    (Win32Api.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.KeyboardHookStruct));

                Keys keyData = (Keys)KeyDataFromHook.vkCode;


                if ((OnKeyDownEvent != null || OnKeyPressEvent != null) &&
                    (wParam == Win32Api.WM_KEYDOWN || wParam == Win32Api.WM_SYSKEYDOWN))

                {
                    if (IsCtrlAltShiftKeys(keyData) && _preKeysList.IndexOf(keyData) == -1)

                    {
                        _preKeysList.Add(keyData);
                    }
                }


                if (OnKeyDownEvent != null && (wParam == Win32Api.WM_KEYDOWN || wParam == Win32Api.WM_SYSKEYDOWN))

                {
                    KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));


                    OnKeyDownEvent?.Invoke(this, e);
                }


                if (OnKeyPressEvent != null && wParam == Win32Api.WM_KEYDOWN)

                {
                    byte[] keyState = new byte[256];

                    Win32Api.GetKeyboardState(keyState);

                    byte[] inBuffer = new byte[2];

                    if (Win32Api.ToAscii(KeyDataFromHook.vkCode, KeyDataFromHook.scanCode, keyState, inBuffer,
                                         KeyDataFromHook.flags) == 1)

                    {
                        KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);

                        OnKeyPressEvent(this, e);
                    }
                }


                if ((OnKeyDownEvent != null || OnKeyPressEvent != null) &&
                    (wParam == Win32Api.WM_KEYUP || wParam == Win32Api.WM_SYSKEYUP))

                {
                    if (IsCtrlAltShiftKeys(keyData))

                    {
                        for (int i = _preKeysList.Count - 1; i >= 0; i--)

                        {
                            if (_preKeysList[i] == keyData)
                            {
                                _preKeysList.RemoveAt(i);
                            }
                        }
                    }
                }


                if (OnKeyUpEvent != null && (wParam == Win32Api.WM_KEYUP || wParam == Win32Api.WM_SYSKEYUP))

                {
                    KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));

                    OnKeyUpEvent?.Invoke(this, e);
                }
            }

            return(Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam));
        }