使用c#中的鼠标全局钩子获取leftclick状态的int

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用c#中的鼠标全局钩子获取leftclick状态的int相关的知识,希望对你有一定的参考价值。

我是c#/ winforms的新手,我希望将鼠标状态作为int来检查它是否在“if”语句中。 (例如,左键单击)

所以我发现了一个全局鼠标钩[这里] [1],效果很好。

但我不明白我如何将鼠标状态作为int,我在论坛和维基上搜索了很长时间。

我在hookCallback中创建一个int时遇到错误,其中检查了单击状态(如果我也明确了)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            MouseHook.Start();
            MouseHook.MouseAction += ne

w EventHandler(Event);
        }

    private void Event(object sender, EventArgs e) { Console.WriteLine("Left mouse click!"); }
}

public static class MouseHook
{
    public static event EventHandler MouseAction = delegate { };

    public static void Start()
    {
        _hookID = SetHook(_proc);


    }
    public static void stop()
    {
        UnhookWindowsHookEx(_hookID);
    }

    private static LowLevelMouseProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    private static IntPtr SetHook(LowLevelMouseProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_MOUSE_LL, proc,
              GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(
      int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
        {
            MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
            MouseAction(null, new EventArgs());
           ******** public int LeftClick = 1; *********
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    private const int WH_MOUSE_LL = 14;

    private enum MouseMessages
    {
        WM_LBUTTONDOWN = 0x0201,
        WM_LBUTTONUP = 0x0202,
        WM_MOUSEMOVE = 0x0200,
        WM_MOUSEWHEEL = 0x020A,
        WM_RBUTTONDOWN = 0x0204,
        WM_RBUTTONUP = 0x0205
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int x;
        public int y;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public uint mouseData;
        public uint flags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
      LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
      IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);


}

}

答案

Add my class to your project

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows.Input;

namespace Hector.Framework.Utils
{
    public class Peripherals
    {
        public class Mouse
        {
            public static int X
            {
                get => Cursor.Position.X;
            }

            public static int Y
            {
                get => Cursor.Position.Y;
            }

            public static void MoveToPoint(int X, int Y)
            {
                Win32.SetCursorPos(X, Y);
            }

            public static void Hide()
            {
                Cursor.Hide();
            }

            public static void Show()
            {
                Cursor.Show();
            }

            public static bool IsHidden
            {
                get => Cursor.Current == null;
            }

            /// <summary>
            /// ButtonNumber: 0-None 1-Left 2-Middle 3-Right 4-XButton1 5-XButton2
            /// </summary>
            public static bool MouseButtonIsDown(int ButtonNumber)
            {
                bool outValue = false;
                bool isLeft = Control.MouseButtons == MouseButtons.Left;
                bool isRight = Control.MouseButtons == MouseButtons.Right;
                bool isMiddle = Control.MouseButtons == MouseButtons.Middle;
                bool isXButton1 = Control.MouseButtons == MouseButtons.XButton1;
                bool isXButton2 = Control.MouseButtons == MouseButtons.XButton2;

                switch (ButtonNumber)
                {
                    case 0:
                        outValue = false;
                        break;
                    case 1:
                        outValue = isLeft;
                        break;
                    case 2:
                        outValue = isMiddle;
                        break;
                    case 3:
                        outValue = isRight;
                        break;
                    case 4:
                        outValue = isXButton1;
                        break;
                    case 5:
                        outValue = isXButton2;
                        break;
                }

                return outValue;
            }

            /// <summary>
            /// This function is in Alpha Phase
            /// </summary>
            /// <param name="FocusedControl">The control that is scrolled; If the control has no focus, it will be applied automatically</param>
            /// <param name="FontSize">This is used to calculate the number of pixels to move, its default value is 20</param>
            static int delta = 0;
            static int numberOfTextLinesToMove = 0;
            static int numberOfPixelsToMove = 0;
            public static bool GetWheelValues(Control FocusedControl, out int Delta, out int NumberOfTextLinesToMove, out int NumberOfPixelsToMove, int FontSize = 20)
            {
                try
                {
                    if (FocusedControl == null) throw new NullReferenceException("The FocusedControl can not bel null");
                    if (!FocusedControl.Focused) FocusedControl.Focus();
                    FocusedControl.MouseWheel += (object sender, MouseEventArgs e) =>
                    {
                        delta = e.Delta;
                        numberOfTextLinesToMove = e.Delta * SystemInformation.MouseWheelScrollLines / 120;
                        numberOfPixelsToMove = numberOfTextLinesToMove * FontSize;
                    };

                    Delta = delta;
                    NumberOfTextLinesToMove = numberOfTextLinesToMove;
                    NumberOfPixelsToMove = numberOfPixelsToMove;

                    return true;
                }
                catch
                {
                    Delta = 0;
                    NumberOfTextLinesToMove = 0;
                    NumberOfPixelsToMove = numberOfPixelsToMove;

                    return false;
                }
            }

            private class Win32
            {
                [DllImport("User32.Dll")]
                public static extern long SetCursorPos(int x, int y);

                [DllImport("User32.Dll")]
                public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point);

                [StructLayout(LayoutKind.Sequential)]
                public struct POINT
                {
                    public int x;
                    public int y;
                }
            }
        }
    }
}

然后,您需要检查鼠标的状态,写下以下内容:

bool MouseLeftButton = Hector.Framework.Utils.Peripherals.Mouse.MouseButtonIsDown(1);

记住:按下所选按钮时,bool为true,当按钮释放时,bool为false

ButtonNumbers:

  • 0 - 没有,
  • 1 - 左,
  • 2 - 中间,
  • 3 - 对,
  • 4 - XButton1,
  • 5 - XButton2

以上是关于使用c#中的鼠标全局钩子获取leftclick状态的int的主要内容,如果未能解决你的问题,请参考以下文章

wpf仿qq边缘自动停靠,支持多屏

c++:使用全局鼠标钩子重新定位窗口

注册一个全局钩子来检测鼠标是不是拖动文件/文本

单击标题栏按钮时,全局低级鼠标钩子会导致冻结

dotnet C# 全局 Windows 鼠标钩子

dotnet C# 全局 Windows 鼠标钩子