“队列空”例外

时间:2016-03-24 22:04:37

标签: c# sendkeys keyboard-hook

当我使用SendKeys.SendWait时,我得到了一些“队列空”异常,这是它的痕迹

   at System.Collections.Queue.Dequeue()
   at System.Windows.Forms.SendKeys.SendInput(Byte[] oldKeyboardState, Queue    previousEvents)
   at System.Windows.Forms.SendKeys.Send(String keys, Control control, Boolean wait)
   at System.Windows.Forms.SendKeys.SendWait(String keys)
   at WindowsFormsApplication2.InterceptKeys.HookCallback(Int32 nCode, IntPtr wParam, IntPtr lParam) in e:\Programing\C#\TypeHebrew\WindowsFormsApplication2\InterceptKeys.cs:line 69

这是我的过程

 private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);

                if (vkCode == 160 || vkCode == 161) { shift = 1; }
                if (vkCode == 162 || vkCode == 163) { ctrl = 1; }
                if (vkCode == 164 || vkCode == 165) { alt = 1; }
                Console.WriteLine(vkCode + "_" + shift);
                int res = replaceKey.getReplacedKey(vkCode, shift);
                if (res != -1 && ctrl == 0 && alt == 0 && getCurrentKeyboardLangauge().Contains("Hebrew"))
                {
                    try
                    {
                        SendKeys.SendWait(char.ConvertFromUtf32((int)res));
                    }
                    catch (Exception ex)
                    {
                        Debug.Print(ex.Message);
                    }
                    return (System.IntPtr)1;
                }else if(getCurrentKeyboardLangauge().Contains("Hebrew") && (vkCode == 79 || vkCode == 89 ||  vkCode == 69 ||  vkCode == 81 ||  vkCode == 220 ||  vkCode == 77 ||  vkCode == 78 ||  vkCode == 66 ||  vkCode == 76 ||  vkCode == 88 ||  vkCode == 90 ||  vkCode == 226)){
                    return (System.IntPtr)1;
                }
            }
            else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                //Console.WriteLine(vkCode);
                if (vkCode == 160 || vkCode == 161) { shift = 0; }
                if (vkCode == 162 || vkCode == 163) { ctrl = 0; }
                if (vkCode == 164 || vkCode == 165) { alt = 0; }                
            }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

任何帮助

1 个答案:

答案 0 :(得分:1)

我认为问题的出现是因为发送的密钥被“重新挂钩”,所以一次又一次地发送和重新挂钩......

为了在类似的情况下避免这种情况,我必须设置一个临时布尔值来知道密钥是否是用户发送的真实按键笔划或我的程序刚刚通过SendKeys方法发送的密钥。

尝试这样的事情:

 private static bool _intercept = true;

 private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
 {
      if (_intercept)
      {
           if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
           {
               int vkCode = Marshal.ReadInt32(lParam);

               if (vkCode == 160 || vkCode == 161) { shift = 1; }
               if (vkCode == 162 || vkCode == 163) { ctrl = 1; }
               if (vkCode == 164 || vkCode == 165) { alt = 1; }
               Console.WriteLine(vkCode + "_" + shift);
               int res = replaceKey.getReplacedKey(vkCode, shift);
               if (res != -1 && ctrl == 0 && alt == 0 && getCurrentKeyboardLangauge().Contains("Hebrew"))
               {
                   try
                   {
                       _intercept = false; // Stop listening keystroke for the next key
                       SendKeys.SendWait(char.ConvertFromUtf32((int)res));
                   }
                   catch (Exception ex)
                   {
                       Debug.Print(ex.Message);
                   }
                   finally
                   {
                       _intercept = true; // Reactivate listening keystroke for the next key
                   }
                   return (System.IntPtr)1;
               }
               else if (getCurrentKeyboardLangauge().Contains("Hebrew") && (vkCode == 79 || vkCode == 89 || vkCode == 69 || vkCode == 81 || vkCode == 220 || vkCode == 77 || vkCode == 78 || vkCode == 66 || vkCode == 76 || vkCode == 88 || vkCode == 90 || vkCode == 226))
               {
                   return (System.IntPtr)1;
               }
           }
           else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP)
           {
               int vkCode = Marshal.ReadInt32(lParam);
               //Console.WriteLine(vkCode);
               if (vkCode == 160 || vkCode == 161) { shift = 0; }
               if (vkCode == 162 || vkCode == 163) { ctrl = 0; }
               if (vkCode == 164 || vkCode == 165) { alt = 0; }
           }
       }
       return CallNextHookEx(_hookID, nCode, wParam, lParam);
   }

您可以在此处的AutoTyper应用程序中看到类似的方法:https://github.com/nmariot/AutoTyper