WH_MOUSE可以捕获全局事件吗?

时间:2014-02-23 20:57:45

标签: c# wpf setwindowshookex

我正在尝试开发一个WPF C#应用程序,即使(因为它是在后台才能启动另一项任务),甚至(特别是)捕获鼠标点击。

在MSDN文档(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx)上,我可以读到WH_MOUSE应该具有全局或线程范围。

我以这种方式实例化我的钩子句柄:

hHook = SetWindowsHookEx(WH_MOUSE,
                        MouseHookProcedure,
                        (IntPtr)0, 
                        AppDomain.GetCurrentThreadId());

其中MouseHookProcedure是我的回调函数的委托,WH_MOUSE值是7(在Winuser.h之后)。

代码有效但它只能捕获本地点击(我只需要WM_LBUTTONDOWN消息),窗口内的点击。我需要在窗口外面和窗口处于后台时捕获点击。

我尝试连接到WH_MOUSE_LL(值为14),但它无效。

在大多数情况下,我遵循这个: http://support.microsoft.com/kb/318804 因为我使用WPF而不是WinForms,所以有一些变化。

关于Hooks的文档有点令人困惑。 总而言之,我想知道:

  • WH_MOUSE可以全局检测鼠标消息吗?如果是的话,我做错了什么?
  • 我可以从.NET C#代码挂钩到WH_MOUSE_LL吗?如果是,怎么样?

提前致谢。

2 个答案:

答案 0 :(得分:1)

WH_MOUSE_LL可以实现,你需要它。

在我的情况下,我开发了一个全局键盘,也许这可以帮助你。 我需要在第三个参数中调用LoadLibrary

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string fileName);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

 void MyFunction(){
     [...]
     SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, LoadLibrary("user32.dll"), 0);
 }

答案 1 :(得分:0)

从技术上讲,你应该能够在C#中实现全局鼠标钩子。然后,您将传递零作为SetWindowsHookEx的最后一个参数,并且您的钩子过程必须驻留在DLL中,而不是EXE中。这是因为DLL将被注入到每个进程中,这些进程的窗口属于与挂钩应用程序相同的桌面。出于同样的原因,大多数人并不推荐在.NET中编写全局钩子,因为它会导致CLR加载到每个桌面进程中,这会带来很大的开销。