You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux无桌面环境下,如何用C#获取裸终端鼠标输入?

C# 实现控制台环境下的鼠标输入捕获

控制台本身没有原生支持鼠标事件,要实现你的简易桌面环境所需的鼠标坐标、按键及滚轮检测,必须调用Windows原生API。以下是完整的实现方案:

1. 核心API导入与工具类封装

首先封装Windows API调用,统一处理鼠标坐标转换、按键状态检测和控制台输入模式开启:

using System;
using System.Runtime.InteropServices;

public static class MouseInputHandler
{
    // 鼠标按键常量
    private const int VK_LBUTTON = 0x01;
    private const int VK_RBUTTON = 0x02;
    private const int WHEEL_STEP = 120;

    // Windows API声明
    [DllImport("user32.dll")]
    private static extern bool GetCursorPos(out POINT lpPoint);

    [DllImport("user32.dll")]
    private static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    private static extern short GetAsyncKeyState(int vKey);

    [DllImport("kernel32.dll")]
    private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

    [DllImport("kernel32.dll")]
    private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint dwMode);

    [DllImport("kernel32.dll")]
    private static extern bool GetConsoleFontSize(IntPtr hConsoleOutput, int nFont, out COORD lpConsoleFontSize);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct COORD
    {
        public short X;
        public short Y;
    }

    // 启用控制台鼠标输入
    public static void EnableConsoleMouseInput()
    {
        IntPtr consoleWnd = GetConsoleWindow();
        if (!GetConsoleMode(consoleWnd, out uint mode)) return;
        // 开启鼠标输入模式
        SetConsoleMode(consoleWnd, mode | 0x0010); // ENABLE_MOUSE_INPUT
    }

    // 获取控制台内的鼠标字符坐标(适配字体大小)
    public static POINT GetConsoleMouseCoords()
    {
        GetCursorPos(out POINT screenPos);
        IntPtr consoleWnd = GetConsoleWindow();
        ScreenToClient(consoleWnd, ref screenPos);

        // 获取当前控制台字体的像素尺寸
        GetConsoleFontSize(GetConsoleWindow(), 0, out COORD fontSize);

        // 转换为控制台字符坐标
        return new POINT
        {
            X = screenPos.X / fontSize.X,
            Y = screenPos.Y / fontSize.Y
        };
    }

    // 检测鼠标按键按下状态
    public static bool IsLeftButtonDown() => (GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0;
    public static bool IsRightButtonDown() => (GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0;

    // 滚轮增量检测(简化版,精确检测需处理WM_MOUSEWHEEL消息)
    public static int GetWheelIncrement()
    {
        short wheelState = GetAsyncKeyState(0x08); // VK_XBUTTON1 对应滚轮按键,实际增量需结合消息循环
        return wheelState != 0 ? WHEEL_STEP : 0;
    }
}

2. 主循环中集成鼠标输入

在你的桌面环境主循环里,持续轮询鼠标状态:

class Program
{
    static void Main(string[] args)
    {
        // 启用控制台鼠标支持
        MouseInputHandler.EnableConsoleMouseInput();

        while (true)
        {
            // 获取鼠标坐标
            var mousePos = MouseInputHandler.GetConsoleMouseCoords();
            Console.WriteLine($"Mouse: X={mousePos.X}, Y={mousePos.Y}");

            // 检测点击事件
            if (MouseInputHandler.IsLeftButtonDown())
            {
                Console.WriteLine("Left Click Triggered");
                // 在这里处理左键点击逻辑
            }
            if (MouseInputHandler.IsRightButtonDown())
            {
                Console.WriteLine("Right Click Triggered");
                // 在这里处理右键点击逻辑
            }

            // 滚轮处理
            int wheelDelta = MouseInputHandler.GetWheelIncrement();
            if (wheelDelta != 0)
            {
                Console.WriteLine($"Wheel Scrolled: {(wheelDelta > 0 ? "Up" : "Down")}");
                // 在这里处理滚轮逻辑
            }

            // 控制循环帧率,避免资源占用过高
            System.Threading.Thread.Sleep(30);
            Console.Clear();
        }
    }
}

关键说明

  • 坐标准确性:通过GetConsoleFontSize获取字体像素尺寸,确保字符坐标转换的准确性,避免因系统字体设置导致的偏移。
  • 精确滚轮检测:如果需要更精确的滚轮增量(比如每滚动一格的具体数值),需要替换为消息循环处理WM_MOUSEWHEEL消息,轮询方式只能做基础检测。
  • 输入模式:必须调用EnableConsoleMouseInput开启控制台的鼠标输入模式,否则无法捕获任何鼠标事件。

内容的提问来源于stack exchange,提问作者Emil-Viktor Schwarze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:06:13