简体   繁体   English

键盘挂钩存放键

[英]Keyboard hook storing keys

I have implemented a keyboard hook as presented in this answer. 我已经实现了答案中介绍的键盘挂钩。 Everything works fine except for one case. 除了一种情况,一切正常。 If I want to hold a key pressed for some time, thus technically remaning in the method which I'm calling, two thing happen: 如果我想按住某个键一段时间,从而在技术上还剩下我要调用的方法,则会发生两件事:

  1. I remain in the method (which is good) 我留在方法中(很好)
  2. the application records the key being held down, as independent keystrokes which are then captured by the hook. 应用程序将被按下的键记录为独立的击键,然后由挂钩捕获。

Hook: 钩:

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;
    }

PerformCombo code PerformCombo代码

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);


    }  

I have tried to use flags, but they didn't seem to work either. 我尝试使用标志,但是它们似乎也没有用。 When inspecting the using the debugger, I've noticed that it constantly goes onto the handler and continously perfoms the action for the BattleKey1 case, even after releasing the key. 在检查使用调试器的过程中,我注意到它不断进入处理程序,并持续执行BattleKey1情况下的动作,即使释放了钥匙也是如此。

As a fast workaround, if you know Maximum combo time: Add new DateTime variable befor do-while : 作为快速的解决方法,如果您知道最大组合时间:在do-while之前添加新的DateTime变量:

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

Add time check at do-while : do-while添加时间检查:

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

This wouldn't delete application freezes (you need to run in Async this methods to do so), but will make a solid case for do-while to break it, if you press some key for a long time. 这不会删除应用程序freezes (您需要在Async中运行此方法来执行此操作),但是如果您长时间按某些键,则可以在do-while打破它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM