键盘挂钩存储键

问题描述:

我已经实现了一个键盘挂钩,如this提供的答案。除了一种情况,一切正常。如果我想抱着压制了一段时间的关键,在我打电话的方法,从而在技术上remaning两两件事发生:键盘挂钩存储键

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

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


    } 

我曾尝试使用国旗,但他们似乎并没有擦出火花。在检查使用调试器时,我注意到它不断地进入处理程序,并持续执行BattleKey1案件的动作,即使在释放密钥后也是如此。

+0

我不知道你为什么使用睡眠......但事实如此。 通常如果你想结合一些输入事件(多键/鼠标点击),你需要存储一个值和开始时间,并检查时间并根据当前时间与新的时间进行比较。这将帮助您将少量事件组合到“事件流”(组合)中。 – Shakra

+0

@Shakra我不知道如何在这类问题上应用事件流。睡觉只是为了在动作之间产生延迟。如果我将它们取出,只处理非常多的操作 –

作为一个快速的解决方法,如果你知道最大连击时间: 添加新DateTime变量befor do-while

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

do-while添加时间检查:

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

这不会删除应用程序freezes(您需要在Async中运行此方法才能这样做),但会为do-while打破它,如果您按某个键为al时间。