windows 如何使用 C# 在系统范围内禁用鼠标单击事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4524608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I disable mouse click event system wide using C#?
提问by Ben
Hey guys, I have a laptop with a very sensitive touch pad, and wanted to code a small program that could block the mouse input when I was typing a paper or something.
嘿伙计们,我有一台带有非常敏感的触摸板的笔记本电脑,我想编写一个小程序,当我打字时可以阻止鼠标输入。
I didn't think it would be hard to do, considering everything I've seen on low-level hooks, but I was wrong (astounding, right?).
考虑到我在低级钩子上看到的所有内容,我认为这并不难,但我错了(令人震惊,对吧?)。
I looked at a few examples, but the examples I've seen either block both keyboard and mouse, or just hide the mouse.
我查看了一些示例,但我所看到的示例要么同时阻止了键盘和鼠标,要么只是隐藏了鼠标。
Any help with this would be great.
对此的任何帮助都会很棒。
回答by Cody Gray
As you mentioned, you can do this using a low-level mouse hook(WH_MOUSE_LL)
, albeit somewhat incorrectly. What happens when you set a hook is that you'll receive notifications on each mouse input event (WM_MOUSEMOVE
, WM_LBUTTONDOWN
, WM_RBUTTONDOWN
, WM_MBUTTONDOWN
, WM_XBUTTONDOWN
, WM_NCXBUTTONDOWN
, the equivalent up events for each of those, WM_MOUSEWHEEL
, and WM_MOUSEHWHEEL
). Once you've finished processing each event, you're supposedto call the CallNextHookEx
function, which passes the event information on to the next application in the hook chain. However, if you want to prevent any other program from getting mouse input information, you can just skip calling that function at the end of your hook procedure. The "Remarks" section of the above-linked documentation explains it thusly:
正如您所提到的,您可以使用低级鼠标挂钩( WH_MOUSE_LL)
,尽管有些不正确。设置挂钩时会发生什么,您将收到有关每个鼠标输入事件的通知 ( WM_MOUSEMOVE
, WM_LBUTTONDOWN
, WM_RBUTTONDOWN
, WM_MBUTTONDOWN
, WM_XBUTTONDOWN
, WM_NCXBUTTONDOWN
,事件,WM_MOUSEWHEEL
, 和WM_MOUSEHWHEEL
)。一旦你完成了每个事件的处理,你应该调用这个CallNextHookEx
函数,它将事件信息传递给钩子链中的下一个应用程序。但是,如果您想阻止任何其他程序获取鼠标输入信息,您可以在钩子过程结束时跳过调用该函数。上述链接文档的“备注”部分对此进行了解释:
Calling CallNextHookExis optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookExunless you absolutely need to prevent the notification from being seen by other applications.
调用CallNextHookEx是可选的,但强烈推荐;否则,安装了钩子的其他应用程序将不会收到钩子通知,因此可能会出现不正确的行为。除非您绝对需要防止其他应用程序看到通知,否则您应该调用CallNextHookEx。
And as it turns out, low-level mouse hooks aren't actually that difficult in C#. I just coded one up myself, actually. But rather than posting that monstrosity of a library, I'll refer you to the simpler code snippet posted on Stephen Toub's blog, which I've reprinted here with syntax highlighting for convenience:
事实证明,低级鼠标挂钩在 C# 中实际上并不困难。实际上,我只是自己编码了一个。但是,我不会发布库的那个怪物,而是将您推荐给Stephen Toub 的博客上发布的更简单的代码片段,为了方便起见,我在此处重印了语法突出显示:
class InterceptMouse
{
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 &&
MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
As I explained above, you'll want to modify his HookCallback
method not to call CallNextHookEx
once you've finished processing the mouse event, but return something like new IntPtr(1)
instead.
正如我在上面解释的那样,您需要修改他的HookCallback
方法,使其CallNextHookEx
在处理完鼠标事件后不再调用,而是返回类似的内容new IntPtr(1)
。
EDIT:And yeah, as others mentioned, there are probably other easier, cleaner solutions to this problem. Your trackpad drivers are a great place to look for an option like "Ignore accidental mouse input while typing". If you don't have this option, you're probably using the standard Windows mouse drivers. Try to download the drivers from your trackpad's manufacturer from the laptop manufacturer's website (for what it's worth, most of the non-Apple trackpads I've seen are Synaptics).
编辑:是的,正如其他人提到的,对于这个问题,可能还有其他更简单、更清洁的解决方案。您的触控板驱动程序是寻找“键入时忽略意外的鼠标输入”等选项的好地方。如果您没有此选项,则您可能正在使用标准的 Windows 鼠标驱动程序。尝试从笔记本电脑制造商的网站上从触控板制造商处下载驱动程序(就其价值而言,我见过的大多数非 Apple 触控板都是Synaptics)。
回答by Tim
A lot of touchpad drivers have this as an option. I.e. When you are typing, it ignores touchpad input. You could also turn off the tap-click, relying on the actual touchpad buttons to click.
许多触摸板驱动程序都将此作为选项。即当您打字时,它会忽略触摸板输入。您还可以关闭点击点击,依靠实际的触摸板按钮进行点击。
First try the driver's configuration utility, before you try to write your own.
首先尝试驱动程序的配置实用程序,然后再尝试编写您自己的配置实用程序。