简体   繁体   中英

SetWindowsHookEx and clicking minimize/maximize/close buttons on form freezing

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM