【问题标题】:Keyboard hook storing keys键盘挂钩收藏键
【发布时间】:2017-07-18 00:01:02
【问题描述】:

我已经实现了一个键盘钩子,如this 回答中所述。除一种情况外,一切正常。如果我想按住某个键一段时间,从而在技术上保留在我正在调用的方法中,会发生两件事:

  1. 我坚持方法(这很好)
  2. 应用程序将按住的键记录为独立的击键,然后由挂钩捕获。

钩子:

private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {

        const int WM_HOTKEY = 0x0312;
            switch (msg)
            {
                case WM_HOTKEY:
                    if (battleBotStatus == 0)
                    {
                        switch (wParam.ToInt32())
                        {

                            case HOTKEY_ID:
                                OnHotKeyPressed();
                                handled = true;
                                break;

                            case HOTKEY_ID9:
                                enableBattleBotKeys();
                                battleBotStatus = 1;
                                //performCombo();
                                handled = true;
                                break;
                        }
                    }
                    else
                    {
                        switch (wParam.ToInt32())
                        {

                            case BattleKey1:
                                performCombo(1);
                                handled = true;                                    
                                buttonIsPressed = false;
                                break;
                        }
                    }
                    break;
            }
        return IntPtr.Zero;
    }

执行组合代码

private void performCombo(int n)
        {
            string simpleAction;
            Sleep(cmbDelay);
            Key k = new Key();
            switch (n) 
            {
                case 1:
                    k = Key.D1;
                    break;
                case 2:
                    k = Key.D2;
                    break;
                case 3:
                    k = Key.D3;
                    break;
                case 4:
                    k = Key.D4;
                    break;
                case 5:
                    k = Key.D5;
                    break;
                case 6:
                    k = Key.D6;
                    break;
            }
        if ((Keyboard.GetKeyStates(k) & KeyStates.Down) > 0)
            Sleep(1000);
        do
        {
            if (comboList[n - 1].Count > 0)
            {
                foreach (string action in comboList[n - 1])
                {
                    simpleAction = action.Split('~')[0];
                    if (simpleAction.Length == 1)
                    {
                        dkeyinput(simpleAction, gamePid, 500);
                        Sleep(cmbDelay);
                    }
                    else
                    {
                        if (simpleAction == "LeftClick")
                        {
                            dmouseclick("left", 300);
                            Sleep(cmbDelay);
                        }
                        else if (simpleAction == "RightClick")
                        {
                            dmouseclick("right", 300);
                            Sleep(cmbDelay);
                        }
                        else if (simpleAction == "Space")
                        {
                            dkeyinput("\"{SPACE}\"", gamePid);
                            Sleep(cmbDelay);
                        }
                        else if (simpleAction.Contains("&"))
                        {
                            dkeyinput2(simpleAction, cmbDelay);
                            Sleep(cmbDelay);
                        }
                    }
                }
            }
        }
        while ((Keyboard.GetKeyStates(k) & KeyStates.Down) > 0);


    }  

我曾尝试使用标志,但它们似乎也不起作用。在检查使用调试器时,我注意到它不断进入处理程序并不断执行BattleKey1 案例的操作,即使在释放密钥之后也是如此。

【问题讨论】:

  • 我不知道你为什么使用睡眠......但就是这样。通常如果您想组合一些输入事件(多次键/鼠标单击),您需要存储一个值和开始时间,并检查 em 并根据当前时间与新的比较。这将帮助您将几个事件组合成一个“事件流”(组合)。
  • @Shakra 我不知道如何将事件流应用于此类问题。睡眠只是为了在动作之间造成延迟。如果我把它们拿出来,只会处理非常多的操作

标签: c# wpf keystroke keyboard-hook


【解决方案1】:

作为一种快速解决方法,如果您知道最大连击时间: 在do-while 之前添加新的DateTime 变量:

var comboStart = DateTime.Now;
do{...}while

do-while添加时间检查:

while ((Keyboard.GetKeyStates(k) & KeyStates.Down) > 0 ||
(DateTime.Now - comboStart).TotalSeconds > maxComboTimeInSeconds);

这不会删除应用程序freezes(您需要在异步中运行此方法才能执行此操作),但如果您长时间按下某个键,则会为do-while 打破它提供一个可靠的案例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2015-09-22
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多