WPF中的全局鼠标钩子

3

我需要获取屏幕上的鼠标位置,而不是我的应用程序内部的位置。

我已经在这里使用了全局鼠标和键盘钩子(点击链接)

在winforms下工作正常,但在wpf下无法工作。

我正在使用代码的版本1,并使用以下内容:

var activity = new UserActivityHook();
activity.OnMouseActivity += activity_OnMouseActivity;

但是,它没有起作用,而是给了我以下错误:

其他信息:找不到指定的模块

下面是相关代码:

public void Start(bool InstallMouseHook, bool InstallKeyboardHook)
{
    // install Mouse hook only if it is not installed and must be installed
    if (hMouseHook == 0 && InstallMouseHook)
    {
        // Create an instance of HookProc.
        MouseHookProcedure = new HookProc(MouseHookProc);

        //install hook
        hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure,
            Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
        //If SetWindowsHookEx fails.
        if (hMouseHook == 0)
        {
            //Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set. 
            int errorCode = Marshal.GetLastWin32Error();
            //do cleanup
            Stop(true, false, false);
            //Initializes and throws a new instance of the Win32Exception class with the specified error. 
            throw new Win32Exception(errorCode);
        }
    }
}

有没有WPF的替代方案或者我错过了什么?


2
什么是NullReferenceException,我该如何修复它? - Soner Gönül
@SonerGönül 我只在WPF中遇到这个错误,但在WinForms中它运行良好。因此,该链接对我的问题没有帮助。 - Suraj Bhawal
1
为了详细说明Soner Gonul的大部分无信息回答,看起来您没有初始化UserActivityHook。 - Greg B
你只是想获取鼠标位置吗? - Blorgbeard
是的,我有最新版本... 但正如我所说,它适用于WinForms,但不适用于WPF。 - Suraj Bhawal
显示剩余3条评论
2个回答

10

dotctor的回答给出了鼠标位置,但不是我正在寻找的事件。

所以我自己想出了解决方法。以下是我为了将来参考而发现的内容。

我们需要改变:

//install hook
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure,
             Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

转至以下内容:

// Install hook
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, IntPtr.Zero, 0);

或者您可以从这里下载编辑后的cs文件,然后我们可以使用该事件。

activity.OnMouseActivity += activity_OnMouseActivity;

我们可以使用e.Xe.Y获取鼠标位置。


1
链接已失效,真遗憾。我们有什么办法可以修复吗?(Wayback机器无法使用)。 - Issung
@JG3 抱歉,我已经没有那些文件了。不过无论如何,你只需要按照上面指定的方式编辑代码,就可以继续进行了。 - Suraj Bhawal

1
  1. Get help from a wizard! (do it the easy way)
    add reference to System.Windows.Forms and use Control.MousePosition

  2. Become an alchemist! (combine your items)
    combine Visual.PointToScreen and Mouse.GetPosition and Application.Current.MainWindow

  3. Use an energy chakra (win32)

     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     internal static extern bool GetCursorPos(ref Win32Point pt);
    
     [StructLayout(LayoutKind.Sequential)]
     internal struct Win32Point
     {
       public Int32 X;
       public Int32 Y;
     };
    
     public static Point GetMousePosition()
     {
        var w32Mouse = new Win32Point();
        GetCursorPos(ref w32Mouse);
    
        return new Point(w32Mouse.X, w32Mouse.Y);
     }
    

是的,我可以获取鼠标指针。使用您提供的第三个选项。但是我真正想要的是在鼠标移动时报告鼠标位置。就像我在问题中展示的那样,一种全局鼠标移动事件。无论如何,感谢您的回复,这是我能够得到的最接近的答案。 - Suraj Bhawal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接