设置全局钩子(Hook) 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);
}
}
最佳答案
您需要一个 native 模块的句柄。不要指望这将作为全局 Hook 工作:您的 Hook 实现需要执行 .NET JIT!
事实上,每个非托管进程都将无法执行您的处理程序!我想这就是系统阻塞的原因。
...
重新阅读代码后,您似乎不需要全局 Hook (“this”在其他进程中没有任何意义)。因此,SetWindowsHookEx 的 RTFM 并适当设置最后一个参数。
作为引用,我建议an old question of mine .
关于c# - SetWindowsHookEx 并在窗体卡住时单击最小化/最大化/关闭按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17808074/