Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止鼠标单击期间发生键盘事件(未释放)_C#_.net_Winforms_Pinvoke - Fatal编程技术网

C# 防止鼠标单击期间发生键盘事件(未释放)

C# 防止鼠标单击期间发生键盘事件(未释放),c#,.net,winforms,pinvoke,C#,.net,Winforms,Pinvoke,我实际上正在进行一个后台处理(在一个新创建的线程中,而不是在deamon中),它允许在特殊的击键上绑定几个动作 我的特殊击键是:鼠标左键单击,在释放单击之前,按键盘上的一些键,然后在鼠标左键释放后,执行一些操作。本部分仅适用于少数软件 例如,在html输入或记事本++中的Google Chrome上,如果我单击然后按下某个键,按下的字母/数字将像往常一样显示,释放时将执行操作(SMFL.Window.Keyboard用于检测按下的键) 我想防止这种默认行为,在“左键单击”期间记录按下的键,并在记

我实际上正在进行一个后台处理(在一个新创建的线程中,而不是在deamon中),它允许在特殊的击键上绑定几个动作

我的特殊击键是:鼠标左键单击,在释放单击之前,按键盘上的一些键,然后在鼠标左键释放后,执行一些操作。本部分仅适用于少数软件

例如,在html输入或记事本++中的Google Chrome上,如果我单击然后按下某个键,按下的字母/数字将像往常一样显示,释放时将执行操作(SMFL.Window.Keyboard用于检测按下的键)

我想防止这种默认行为,在“左键单击”期间记录按下的键,并在记录这些键的情况下继续处理

我有两个想法:

1-使用pInvoke的BlockInput

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool BlockInput([In, MarshalAs(UnmanagedType.Bool)] bool fBlockIt);
但是此方法总是返回false(零)。这是因为当前正在执行输入吗?(按下鼠标左键) 这可能是一个非常好的解决方案,但是:我无法测试它;它是否会阻止每个键盘事件?(如果我无法检索到有关按键的任何信息,则对我的应用程序无效)

2-创建带焦点的不可见窗口

防止特定窗口上发生键盘事件的另一种方法可能是打开一个不可见窗口,将焦点设置在该窗口上,然后在释放鼠标按钮时关闭该窗口。 当按下鼠标按钮时,我无法成功设置新打开窗口的焦点

一些代码:

while (true) // background process listening
{
  if (Mouse.IsButtonPressed(Mouse.Button.Left)) // keyboard/mouse event with SFML
    {
         _focus = new focusManager(); // Start new thread to create new invisible window
         Thread thread = new Thread(new ThreadStart(_focus.preventFocus));
         thread.Start();
         _focus.forceFocus ();
    }
  else
    {
         _focus.giveFocus ();
    }

}

知道为什么BlockInput总是返回False吗? 你知道我为什么不能把焦点放在这个新窗口上吗? 最后一种情况:有没有其他方法可以防止特定应用程序上的键盘行为(chrome、norepad++……,我的击键操作的目标)


非常感谢

使用键盘挂钩是找到的最佳工作解决方案。我使用了一个Kb钩子,而不是代码项目中的这个钩子,它更容易使用,也更紧凑

为了阻止当前窗口上键的处理,回调必须返回1,而不是
CallNextHookEx
windowsapi函数的值

在Github上找到的项目中,回调为:

private IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
并替换最后一行:

return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);

小心点


CallNextHookEx
方法(此处在
InterceptKeys
类中定义)调用键事件的下一个钩子。如果替换该调用,则不会再处理按键事件,这可能是危险的,因为目标应用程序可能有自己的键盘挂钩。

BlockInput()需要UAC提升。你不能从一个刚刚有输入事件的窗口偷走焦点。你需要一个键盘挂钩。谢谢,我会做一些研究,我会试试这个
return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
return (IntPtr) 1;