简体   繁体   English

禁用Alt键临时C#

[英]Disable alt key temporary c#

I'm searching a way to disable alt and ctrl key input while I'm pressing it. 我正在寻找一种在按下Alt和Ctrl键时禁用输入的方法。 I'm actually developping a Macro Configurer and when I press my macro (for example Alt+Ctrl+NumPad0) and I want that the keys H+E+L+L+O are sent, it won't work because I'm pressing Alt. 我实际上是在开发一个宏配置器,当我按下宏(例如Alt + Ctrl + NumPad0)并且希望发送键H + E + L + L + O时,它将无法正常工作,因为我按Alt。 The computer probably tries to execute unknown shortcuts for Alt+Ctrl+H, Alt+Ctrl+E ... So I want that when I press my macro and the program detects I pressed it, it disable temporary alt while the output keys are sent, and enable again Alt when it's finished. 计算机可能会尝试执行Alt + Ctrl + H,Alt + Ctrl + E的未知快捷键...因此,我希望当我按下宏并且程序检测到我按下它时,它会在发送输出键时禁用临时Alt ,并在完成后再次启用Alt。 I use a LowLevelKeyboardProc to detect when i press a key, but I can't prevent the Alt pressing because i'm actually pressing it to execute my macro. 我使用LowLevelKeyboardProc来检测何时按下某个键,但是我无法阻止Alt的按下,因为我实际上是在按下它来执行我的宏。

//The code from my form //我表单中的代码

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

} }

You could set a low-level keyboard hook to swallow keyboard input messages in windows. 您可以设置一个low-level keyboard hook以吞没Windows中的键盘输入消息。

Every native Windows program bases on a so called message loop that is basicly this. 每个本地Windows程序都基于所谓的message loop ,基本上就是这样。

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

With an low-level keyboard hook you can handle messages in this loop on the desktop process and with that prevent keys from being pressed. 使用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
}

You can use the code like the following. 您可以使用如下代码。 When you do not call CallNextHookEx the key event will not have any impact. 当您不致电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);

And don't forget to unset the hook. 并且不要忘记解开钩子。

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

UnhookWindowsHookEx(hookID);

Thanks to @Manfred Radlwimmer I solved the problem. 感谢@Manfred Radlwimmer,我解决了这个问题。 I send a Alt and Ctrl key up before executing my action and it works fine. 在执行我的操作之前,我向上发送了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);
        }
    }

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

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