2016-12-11 93 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被釋放。 –