SetWindowsHookEx 并单击表单冻结时的最小化/最大化/关闭按钮
Posted
技术标签:
【中文标题】SetWindowsHookEx 并单击表单冻结时的最小化/最大化/关闭按钮【英文标题】:SetWindowsHookEx and clicking minimize/maximize/close buttons on form freezing 【发布时间】:2013-07-23 10:50:15 【问题描述】:设置全局钩子 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);
【问题讨论】:
这是某种全局钩子吗? @KingKing,是的。这是 MouseDoubleClick 事件的钩子 用户双击后你会做什么?需要用钩子吗?我要问的是你为什么要这样做,因为可能还有其他方法。 @TheKingDave,在大多数程序中,双击文本会导致选择光标下的单词。我需要在双击后立即将突出显示的单词添加到我的程序中,我可以继续使用它。出于这个原因,我需要按照双击,诉诸SetWindowsHookEx ... 【参考方案1】:您需要一个本地模块的句柄。不要期望这将作为一个全局钩子工作:您的钩子实现需要执行 .NET JIT!
确实,每个非托管进程都将无法执行您的处理程序!我想这就是系统阻塞的原因。
...
重新阅读您的代码后,您似乎不需要全局挂钩(“this”在其他进程中没有意义)。因此,SetWindowsHookEx 的 RTFM 并适当地设置最后一个参数。
作为参考,我建议an old question of mine。
【讨论】:
以上是关于SetWindowsHookEx 并单击表单冻结时的最小化/最大化/关闭按钮的主要内容,如果未能解决你的问题,请参考以下文章
SetWindowsHookEx WH_MOUSE 在 Win7 中的断点处冻结
在 Project Navigator 中单击 JSON 文件时 Xcode 冻结(并崩溃)
QT QThread::isrunning 冻结程序在 Pi