首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在C# .netcore中读取按下的键盘和鼠标

在C# .NET Core中读取按下的键盘和鼠标的方法可以使用System.Windows.Forms命名空间中的类来实现。

首先,需要引用System.Windows.Forms命名空间,在项目中添加对System.Windows.Forms.dll的引用。然后,可以使用以下代码来实现读取键盘和鼠标的按下事件:

代码语言:txt
复制
using System;
using System.Windows.Forms;

public class KeyboardMouseReader
{
    public static void Main()
    {
        // 创建一个全局的键盘和鼠标钩子
        using (var hook = new KeyboardMouseHook())
        {
            // 注册键盘和鼠标按下事件的处理方法
            hook.KeyDown += Hook_KeyDown;
            hook.MouseDown += Hook_MouseDown;

            // 启动钩子
            hook.Start();

            // 运行程序直到用户按下ESC键
            while (true)
            {
                if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
                {
                    break;
                }
            }

            // 停止钩子
            hook.Stop();
        }
    }

    private static void Hook_KeyDown(object sender, KeyEventArgs e)
    {
        // 处理按下的键盘事件
        Console.WriteLine("键盘按下:" + e.KeyCode);
    }

    private static void Hook_MouseDown(object sender, MouseEventArgs e)
    {
        // 处理鼠标按下事件
        Console.WriteLine("鼠标按下:" + e.Button);
    }
}

public class KeyboardMouseHook : IDisposable
{
    private readonly IntPtr hookHandle;
    private readonly NativeMethods.HookProc hookCallback;

    public event KeyEventHandler KeyDown;
    public event MouseEventHandler MouseDown;

    public KeyboardMouseHook()
    {
        hookCallback = HookCallback;
        hookHandle = SetHook(hookCallback);
    }

    public void Start()
    {
        // 启动钩子
        NativeMethods.StartHook(hookHandle);
    }

    public void Stop()
    {
        // 停止钩子
        NativeMethods.StopHook(hookHandle);
    }

    private IntPtr SetHook(NativeMethods.HookProc proc)
    {
        using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
        using (var curModule = curProcess.MainModule)
        {
            // 安装钩子
            return NativeMethods.SetWindowsHookEx(
                NativeMethods.WH_KEYBOARD_LL,
                proc,
                NativeMethods.GetModuleHandle(curModule.ModuleName),
                0);
        }
    }

    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0)
        {
            var eventType = (NativeMethods.WindowMessage)wParam;
            if (eventType == NativeMethods.WindowMessage.WM_KEYDOWN)
            {
                var vkCode = Marshal.ReadInt32(lParam);
                var key = (Keys)vkCode;

                // 触发键盘按下事件
                KeyDown?.Invoke(this, new KeyEventArgs(key));
            }
            else if (eventType == NativeMethods.WindowMessage.WM_LBUTTONDOWN ||
                     eventType == NativeMethods.WindowMessage.WM_RBUTTONDOWN ||
                     eventType == NativeMethods.WindowMessage.WM_MBUTTONDOWN)
            {
                var button = GetMouseButtonFromEventType(eventType);

                // 触发鼠标按下事件
                MouseDown?.Invoke(this, new MouseEventArgs(button, 0, 0, 0, 0));
            }
        }

        // 继续执行下一个钩子
        return NativeMethods.CallNextHookEx(hookHandle, nCode, wParam, lParam);
    }

    private MouseButtons GetMouseButtonFromEventType(NativeMethods.WindowMessage eventType)
    {
        switch (eventType)
        {
            case NativeMethods.WindowMessage.WM_LBUTTONDOWN:
                return MouseButtons.Left;
            case NativeMethods.WindowMessage.WM_RBUTTONDOWN:
                return MouseButtons.Right;
            case NativeMethods.WindowMessage.WM_MBUTTONDOWN:
                return MouseButtons.Middle;
            default:
                throw new ArgumentOutOfRangeException(nameof(eventType), eventType, null);
        }
    }

    public void Dispose()
    {
        // 卸载钩子
        NativeMethods.UnhookWindowsHookEx(hookHandle);
    }
}

public static class NativeMethods
{
    public const int WH_KEYBOARD_LL = 13;

    public enum WindowMessage : uint
    {
        WM_KEYDOWN = 0x0100,
        WM_LBUTTONDOWN = 0x0201,
        WM_RBUTTONDOWN = 0x0204,
        WM_MBUTTONDOWN = 0x0207
    }

    public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

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

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

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

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

    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("kernel32.dll")]
    public static extern uint GetCurrentThreadId();

    [DllImport("user32.dll")]
    public static extern IntPtr SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

    [DllImport("user32.dll")]
    public static extern IntPtr GetFocus();

    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

    public static void StartHook(IntPtr hookHandle)
    {
        ShowWindow(GetForegroundWindow(), 2);

        uint currentThreadId = GetCurrentThreadId();
        uint foregroundThreadId = GetWindowThreadProcessId(GetForegroundWindow(), out var _);

        if (currentThreadId != foregroundThreadId)
        {
            AttachThreadInput(currentThreadId, foregroundThreadId, true);
        }

        SetForegroundWindow(hookHandle);

        if (currentThreadId != foregroundThreadId)
        {
            AttachThreadInput(currentThreadId, foregroundThreadId, false);
        }

        SetForegroundWindow(GetFocus());
    }

    public static void StopHook(IntPtr hookHandle)
    {
        ShowWindow(GetForegroundWindow(), 1);
        SetForegroundWindow(hookHandle);
    }
}

这段代码会监听键盘和鼠标的按下事件,并在控制台中打印出按下的按键或鼠标按钮。可以根据需求对事件进行进一步处理。

此外,C# .NET Core还有其他方式可以读取键盘和鼠标的输入,例如使用WindowsAPI函数来监听原始输入,或者使用第三方库如InputSimulator等。具体选择何种方法取决于项目需求和开发偏好。

注意:在使用键盘和鼠标钩子的时候,请确保以管理员身份运行程序,否则可能会无法捕捉系统级别的按键事件。

腾讯云相关产品:

  • 云服务器CVM:https://cloud.tencent.com/product/cvm
  • 弹性伸缩CVM:https://cloud.tencent.com/product/as
  • 云数据库MySQL:https://cloud.tencent.com/product/cdb
  • 弹性公网IP:https://cloud.tencent.com/product/eip
  • 轻量应用服务器Lighthouse:https://cloud.tencent.com/product/lighthouse

请注意,以上链接仅为参考,具体使用腾讯云产品时,请根据实际需求进行选择和配置。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券