在我按下它时,我正在寻找禁用alt和ctrl键输入的方法。 我实际上正在开发一个宏配置器,当我按下我的宏(例如Alt + Ctrl + NumPad0)并且我想要发送键H + E + L + L + O时,它将无法工作,因为我是按Alt键。计算机可能会尝试执行Alt + Ctrl + H,Alt + Ctrl + E的未知快捷方式... 所以我希望当我按下我的宏并且程序检测到我按下它时,它会在发送输出键时禁用临时alt,并在完成时再次启用Alt。 我使用LowLevelKeyboardProc来检测我何时按下一个键,但是我无法阻止Alt按下,因为我实际上正在按它来执行我的宏。
//表单中的代码
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 :(得分:3)
您可以在Windows中设置low-level keyboard hook
以吞下键盘输入消息。
每个本地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);
答案 1 :(得分: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);
}
}