2016-12-11 51 views
0

我正在寻找一种方法来禁用alt和ctrl键输入,而我按它。 我实际上正在开发一个宏配置器,当我按下我的宏(例如Alt + Ctrl + NumPad0)并且我想要发送H + E + L + L + O键时,它将不起作用,因为我'按下Alt键。计算机可能会尝试执行未知的快捷键Alt + Ctrl + H,Alt + Ctrl + E ... 所以我希望当我按下我的宏并且程序检测到我按下它时,它会禁用临时替代项,而输出键是发送,并在完成时再次启用Alt。 我使用LowLevelKeyboardProc来检测当我按下一个键,但我不能防止Alt按下,因为我实际上是按它来执行我的宏。禁用alt键临时c#

//代码从我的形式

private void Listener_OnKeyUp(object sender, KeyUpArgs e) 
{ 
    KeyAction.RemoveKeyDown(e.KeyUp); 
} 


private void Listener_OnKeyPressed(object sender, KeyPressedArgs e) 
{ 
    try 
    { 
     KeyAction.PutKeyDown(e.KeyPressed); 
     foreach (MacroEntree macro in macros) 
     { 
      if (macro.Activated) 
       if (macro.Action != null) 
        if (macro.isMacroDown()) 
        { 
         listener.OnKeyPressed -= new EventHandler<KeyPressedArgs>(Listener_OnKeyPressed); 
         new Thread(delegate() 
         { 
          while (IsAltCtrlDown()) ; 
          macro.ExecuteAction(); 
          Thread.Sleep(100); 
          listener.OnKeyPressed += new EventHandler<KeyPressedArgs>(Listener_OnKeyPressed); 

         }).Start(); 
        } 
     } 
    } 
    catch (Exception ex) 
    { 

     MessageBox.Show("Erreur : " + ex.Message); 
    } 
} 
private bool IsAltCtrlDown() 
{ 
    if (KeyAction.isKeyDown(Key.LeftAlt) || KeyAction.isKeyDown(Key.RightAlt)) 
     return true; 
    if (KeyAction.isKeyDown(Key.LeftCtrl) || KeyAction.isKeyDown(Key.RightCtrl)) 
     return true; 
    return false; 
} 


//the code from my class that checks if the macro is down 
public class KeyAction 
{ 
    static List<Key> keyDown = new List<Key>(); 

    public static bool isKeyDown(Key k) 
    { 
     return keyDown.Contains(k); 
    } 
    public static void PutKeyDown(Key k) 
    { 
     if (!keyDown.Contains(k)) 
      keyDown.Add(k); 
    } 
    public static void RemoveKeyDown(Key k) 
    { 
     keyDown.Remove(k); 
    } 

}

+0

你不能发送'CtrlUp + AltUp'的KeyUp吗?也许这样系统可能会认为你已经释放了密钥(带有keybd_event)。 –

+0

我会试试这个,我没有考虑过。 –

+0

编辑:我只是试了一下,它的工作,这太容易想想....谢谢! –

回答

0

感谢@Manfred Radlwimmer我解决了这个问题。在执行我的动作之前,我发送一个Alt和Ctrl键,它工作正常。

private void Listener_OnKeyPressed(object sender, KeyPressedArgs e) 
    { 
     try 
     { 
      KeyAction.PutKeyDown(e.KeyPressed); 
      foreach (MacroEntree macro in macros) 
      { 
       if (macro.Activated) 
        if (macro.Action != null) 
         if (macro.isMacroDown()) 
         { 
          listener.OnKeyPressed -= new EventHandler<KeyPressedArgs>(Listener_OnKeyPressed); 
          new Thread(delegate() 
          { 
           KeyboardOperations.SendKeyUp(KeyboardOperations.KeyCode.LALT); 
           KeyboardOperations.SendKeyUp(KeyboardOperations.KeyCode.LCONTROL); 

           macro.ExecuteAction(); 
           Thread.Sleep(100); 
           listener.OnKeyPressed += new EventHandler<KeyPressedArgs>(Listener_OnKeyPressed); 

          }).Start(); 
         } 
      } 
     } 
     catch (Exception ex) 
     { 

      MessageBox.Show("Erreur : " + ex.Message); 
     } 
    } 
3

你可以设置一个low-level keyboard hook在Windows吞键盘输入信息。

每个本机Windows程序都基于所谓的message loop,这基本上就是这样。

MSG msg; 
while(GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

随着low-level keyboard hook,你可以在这个循环的过程desktop处理消息,并与阻止按键。

public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr SetWindowsHookEx(
    int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); 

private const int WH_KEYBOARD_LL = 13; 
private static IntPtr SetHook(LowLevelKeyboardProc proc) 
{ 
    return SetWindowsHookEx(
     WH_KEYBOARD_LL, 
     proc, 
     0, // hook on all input (https://stackoverflow.com/questions/7715480/is-zero-ever-a-valid-handle) 
     0); // for all threads 
} 

您可以使用下面的代码。如果您不拨打CallNextHookEx,关键事件不会有任何影响。

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, 
    IntPtr wParam, IntPtr lParam); 

private const int WM_KEYDOWN = 0x0100; 

private static IntPtr HookCallback(
    int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    // check if it is a key down message 
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
    { 
     int vkCode = Marshal.ReadInt32(lParam); 
     // check if the pressed key is the `Alt` key 
     if((Keys)vkCode == Keys.Alt) 
     { 
      // return 1 for handled if its the alt key 
      return (IntPtr) 1; 
     } 
    } 

    // let the message bubble if its not a keydown message or it wasn't the alt key which was pressed    
    return CallNextHookEx(_hookID, nCode, wParam, lParam); 
} 

// with this line you can set the `HookCallback` into the message loop 
IntPtr hookID = SetHook(HookCallback); 

并且不要忘记取消挂钩。

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

UnhookWindowsHookEx(hookID); 
+0

感谢您的回复。我已经试过这个,但是我不能阻止Alt键被按下,如果我真的按下它来执行我的宏。我需要在按下Alt键时禁用Alt键,直到执行的动作完成。 –

+1

@FosheusBadabu代码应该如何确定是否有任何键作为宏的一部分被按下?如果用户按下Alt键,但等了一分半钟才能完成宏,该怎么办? – krillgar

+0

对不起,迟到的答复。宏将执行一分半后,这不是我想要的。我在Hookcallback上有一个表单捕捉的事件。我还有一个类来检查宏是否关闭。当一个钥匙在事件中被捕获时,我检查其他钥匙是否与我的班级一起停下来(这是一个列表,当钥匙处于关闭或关闭状态时,我将它填充并清理),而当宏停机时,我一直等到alt和ctrl被释放。 –