鼠标钩子断开连接

本文关键字:连接 断开 鼠标 | 更新日期: 2023-09-27 18:15:03

我正在尝试实现一个颜色选择器,从屏幕上的每个像素获取颜色。要做到这一点,我计划使用一个全局鼠标钩子来监听WM_MOUSEMOVE,以便在鼠标移动时更新颜色,并监听鼠标点击以确认(WM_LBUTTONDOWN)或取消(WM_RBUTTONDOWN)操作。

我遵循了许多教程中的一个,我想出了这个(在控制台应用程序中,只是为了测试这个过程是否有效):

static IntPtr hook;
static bool click;
static NativeMethods.LowLevelHookStruct llhs;
static void Main(string[] args)
{
  hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0);
  if (hook != IntPtr.Zero)
  {
    Console.WriteLine("Hook Set");
    while (!Console.KeyAvailable) {
      Console.WriteLine("{0} {1} {2}", hook, llhs.pt.x, llhs.pt.y);
      if(click) Console.WriteLine("click!");
      click = false;
      System.Threading.Thread.Sleep(250); 
    }
  }
}

public static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
  if (nCode >= 0)
  {
    NativeMethods.LowLevelHookStruct hookStruct = (NativeMethods.LowLevelHookStruct)Marshal.PtrToStructure(lParam, typeof(NativeMethods.LowLevelHookStruct));
    if (NativeMethods.MouseMessages.WM_MOUSEMOVE == (NativeMethods.MouseMessages)wParam)
    {
      llhs = hookStruct;
    }
    if (NativeMethods.MouseMessages.WM_LBUTTONDOWN == (NativeMethods.MouseMessages)wParam)
    {
      click = true;
    }
    else if (NativeMethods.MouseMessages.WM_RBUTTONDOWN == (NativeMethods.MouseMessages)wParam)
    {
    }
  }
  return NativeMethods.CallNextHookEx(hook, nCode, wParam, lParam);
}

ativeemethods只是一个类,我在其中保存了所有与DllImport相关的东西。

一旦我运行控制台应用程序,鼠标光标卡住了几秒钟,在控制台我得到这个-即使光标卡住

Hook Set
3945554872 0 0
3945554872 0 0
3945554872 0 0
3945554872 0 0
...

在调试中,我的钩子似乎从来没有被调用过,甚至一次都没有。你知道哪里出了问题吗?

鼠标钩子断开连接

根据@Hans Passant的评论,我将我的测试代码移到了WinForms应用程序中,并且回调开始出现。

然后发现回调正在被垃圾收集,所以我所要做的就是改变

hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0);

private NativeMethods.LowLevelHookProc _hookCallback;
...
_hookCallback = new NativeMethods.LowLevelHookProc(MouseHookCallback);
hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, _hookCallback, (IntPtr)null, 0);

,以保持对回调的引用,使其不会被GCed。