设置全局挂钩后,SetWindowsHookEx标准表单的按钮工作奇怪。例如,如果我单击关闭按钮,则鼠标会冻结5-10秒并形成。
我找到了同样问题的主题C# low level mouse hook and form event handling 但只有一个答案。而且我不喜欢这个解决方案,因为它需要每次Hook,表单停用时,以及UnHook,当程序激活时...
有没有更好的方法来解决这个问题?
被修改
这是我的代码:
using System.Windows.Forms;
using Gma.UserActivityMonitor;
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace WinFormsHook
{
public partial class Form1 : Form
{
int s_MouseHookHandle;
public Form1()
{
InitializeComponent();
IntPtr hInst = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
s_MouseHookHandle = SetWindowsHookEx( WH_MOUSE_LL, MouseHookProc, hInst, 0);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
UnhookWindowsHookEx(s_MouseHookHandle);
}
private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode >= 0)
{
Debug.WriteLine(wParam);
if (wParam == WM_LBUTTONDOWN)
{
Action action = () => this.Text += ".";
this.Invoke(action);
}
}
//call next hook
return CallNextHookEx(s_MouseHookHandle, nCode, wParam, lParam);
}
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONDOWN = 0x201;
private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern int UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam);
}
}
答案 0 :(得分:1)
您需要一个本机模块的句柄。不要指望它会作为全局钩子工作:你的钩子实现需要执行.NET JIT!
确实,每个非托管进程都无法执行您的处理程序!我想这就是系统阻塞的原因。
...
重新阅读你的代码后,似乎你不想要一个全局钩子('this'在其他进程中没有意义)。所以,SetWindowsHookEx的RTFM并适当地设置最后一个参数。
作为参考,我建议an old question of mine。