如何使用C#在系统范围内禁用鼠标单击事件?
我有一台笔记本电脑,带有一个非常灵敏的触摸板,我想编写一个小程序,在我打字的时候可以阻止鼠标输入 考虑到我在低级钩子上看到的一切,我并不认为这很难做到,但我错了(令人震惊,对吧?) 我看了几个例子,但我看到的例子要么阻止键盘和鼠标,要么只是隐藏鼠标如何使用C#在系统范围内禁用鼠标单击事件?,c#,windows,winapi,hook,mouse-hook,C#,Windows,Winapi,Hook,Mouse Hook,我有一台笔记本电脑,带有一个非常灵敏的触摸板,我想编写一个小程序,在我打字的时候可以阻止鼠标输入 考虑到我在低级钩子上看到的一切,我并不认为这很难做到,但我错了(令人震惊,对吧?) 我看了几个例子,但我看到的例子要么阻止键盘和鼠标,要么只是隐藏鼠标 这方面的任何帮助都将非常好。许多触摸板驱动程序都将此作为一个选项。也就是说,当你打字时,它会忽略触摸板输入。您也可以关闭点击,依靠实际的触摸板按钮点击 在您尝试编写自己的驱动程序之前,首先尝试驱动程序的配置实用程序。如您所述,您可以使用(WH\u M
这方面的任何帮助都将非常好。许多触摸板驱动程序都将此作为一个选项。也就是说,当你打字时,它会忽略触摸板输入。您也可以关闭点击,依靠实际的触摸板按钮点击
在您尝试编写自己的驱动程序之前,首先尝试驱动程序的配置实用程序。如您所述,您可以使用(
WH\u MOUSE\l)
来完成此操作,尽管有点不正确。当您设置一个钩子时,您将收到每个鼠标输入事件的通知(WM\u MOUSEMOVE
,WM\u LBUTTONDOWN
,WM\u RBUTTONDOWN
,WM\u XBUTTONDOWN
,WM\u NCXBUTTONDOWN
,每种情况下的等效up事件,WM\u mouseweel
,以及WM\u mouseheel
)。处理完每个事件后,您应该调用,该函数将事件信息传递给钩子链中的下一个应用程序。但是,如果您想阻止任何其他程序获取鼠标输入信息,您可以在钩子过程结束时跳过调用该函数。“备注”上述链接文档的一节对此进行了解释:
调用CallNextHookEx是可选的,
但这是强烈推荐的;
否则,其他应用程序
已安装的挂钩将不会收到
钩子通知和可能的行为
结果是错误的。您应该
除非您
绝对需要预防
通知不被其他人看到
应用程序
事实证明,低级鼠标钩子在C#中其实并不难。事实上,我只是自己编写了一个。但是,我不会发布那种怪异的库,我会让你参考上面发布的更简单的代码片段,为了方便起见,我在这里用语法突出显示重印了它:
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);
}
正如我在上面解释的,您需要修改他的HookCallback
方法,在处理完鼠标事件后不要调用callnexthookx
,而是返回类似newintptr(1)
的内容
编辑:是的,正如其他人提到的,可能还有其他更简单、更干净的解决方案。您的触控板驱动程序是一个很好的选择,可以选择“在键入时忽略意外的鼠标输入”。如果您没有此选项,您可能正在使用标准的Windows鼠标驱动程序。请尝试从笔记本电脑制造商的网站下载您的触控板制造商的驱动程序(值得一提的是,我见过的大多数非Apple触控板都是).为什么不使用设备管理器禁用特定的鼠标?可能是更改灵敏度设置,或者像Jon用bat脚本所说的那样。有些笔记本电脑有一个专用按钮。如果您决定使用挂钩,挂钩将显著影响性能。检查键盘……很可能您有停止输入的功能鼠标完全移动。通常在功能键(F1,F2…)上显示为蓝色图标我已经检查过了,没有开关/功能键您可以在“好主意概述”中阅读有关性能问题的内容,但我无法让它工作。尝试将ncode设置为-1,取出回车符,并将方法设置为return void。还有其他想法吗?我甚至无法更改按下的鼠标按钮。@Mazzzz:我建议修改return语句为:
returnnewintptr(1);
。这对我来说很好。如上所述,我刚刚使用完全相同的方法完成了一个库的编写和测试。根本不需要修改nCode
值,而且你不能只更改方法的返回类型。奇怪的是,我尝试了完全相同的方法(和IntPtr.Zero一起)但是没有用。你在运行什么?我在windows 7,C#3.5上有我的。你能给我发你的代码吗,也许我打错了什么。谢谢,我打错了,我用了return new IntPtr(0);不是1,谢谢!你可以执行callnexthookx
然后返回新的IntPtr(1)
,所以每个人都会得到钩子,但如上所述,它会阻止消息传播到窗口。