After setting the global hook SetWindowsHookEx standard form's buttons working oddly. For example, if I click close button, then the mouse freezes for 5-10 seconds and form too.
I found topic with same problem C# low level mouse hook and form event handling but there is only one answer. And I do not like that solution, because it needs to do each time Hook, when form deactivated, and UnHook, when program activated...
Is there a better way to solve this problem?
Edited
Here is my code:
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);
}
}
You need an handle to a native module. Don't expect that this will work as a global hook: your hook implementation requires the .NET JIT to be executed!
Indeed every non-managed process will fail to execute your handler! I suppose that this is the reason of the system block.
...
After re-reading your code it seems you don't want a global hook ('this' has no meanng in other processes). So, RTFM of SetWindowsHookEx and set the last argument appropriately.
For reference, I suggest an old question of mine.
来源:https://stackoverflow.com/questions/17808074/setwindowshookex-and-clicking-minimize-maximize-close-buttons-on-form-freezing