WPF 中的全局鼠标钩子

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27133957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:43:36  来源:igfitidea点击:

Global Mouse Hook in WPF

c#.netwpfhook

提问by Suraj Bhawal

I need to get mouse position on screen NOTinside my application.

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

I've used Global mouse and keyboard hook here

我在这里使用了全局鼠标和键盘钩子

It works fine under winforms but won't work under wpf.

它在 winforms 下工作正常,但在 wpf 下不起作用。

I'm using version1 of the code and used the following

我正在使用代码的 version1 并使用以下内容

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

but instead of working it give me following error:

但不是工作它给了我以下错误:

Additional information: The specified module could not be found

附加信息:找不到指定的模块

under for following code

下面的代码

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);
        }
    }
}

Is there any alternative for WPF or am I missing something?

WPF 有没有其他选择,还是我遗漏了什么?

回答by Suraj Bhawal

dotctor's answer gives the mouse position, but not the event I was looking for...

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

So I figured out on my own. Here are my findings for future reference.

所以我自己想通了。这是我的发现以供将来参考。

We need to change:

我们需要改变:

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

to the following:

到以下几点:

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

Alternatively you can just download the edited cs file from herethen we can use the event

或者,您可以从此处下载编辑过的 cs 文件,然后我们可以使用该事件

activity.OnMouseActivity += activity_OnMouseActivity;

under which we can use e.Xand e.Yto get mouse position.

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

回答by Hamid Pourjam

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

  2. Become an alchemist! (combine your items)
    combine Visual.PointToScreenand Mouse.GetPositionand 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()
    {
       Win32Point w32Mouse = new Win32Point();
       GetCursorPos(ref w32Mouse);
       return new Point(w32Mouse.X, w32Mouse.Y);
    }
    
  1. 向巫师寻求帮助!(用简单的方法做)
    添加引用System.Windows.Forms并使用Control.MousePosition

  2. 成为炼金术士!(组合您的项目)
    组合Visual.PointToScreenMouse.GetPositionApplication.Current.MainWindow

  3. 使用能量脉轮 (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()
    {
       Win32Point w32Mouse = new Win32Point();
       GetCursorPos(ref w32Mouse);
       return new Point(w32Mouse.X, w32Mouse.Y);
    }