首页 > 编程语言 >[C#] 使用 ReadConsoleInput 所需要注意的问题.

[C#] 使用 ReadConsoleInput 所需要注意的问题.

时间:2023-07-01 10:33:59浏览次数:53  
标签:ReadConsoleInput C# public RECORD uint 注意 FieldOffset EVENT PRESSED


如果要使用鼠标输入, 那么需要:

  1. 启用鼠标输入, 只有启用之后, 才能接收到鼠标事件
  2. 关闭控制台的快速编辑模式, 很多人的控制台都启用了快速编辑模式, 它会导致鼠标输入无效

任何情况下, 都需要:

  • 不使用除 ReadConsoleInput 之外的任何输入方法, 因为它们会和你争抢 ReadConsoleInput 的使用.

引用:

参考代码:

internal class NativeApi
{
    public const int STD_OUTPUT_HANDLE = -11;
    public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
    public const uint ENABLE_MOUSE_INPUT = 0x0010;
    public const int STD_INPUT_HANDLE = -10;
    public const uint ENABLE_QUICK_EDIT_MODE = 0x0040;

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetStdHandle(int nStdHandle);

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

    [DllImport("kernel32.dll")]
    public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
    public static void EnableANSI()
    {
        var handle = GetStdHandle(STD_OUTPUT_HANDLE);
        GetConsoleMode(handle, out var mode);
        mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
        SetConsoleMode(handle, mode);
    }
    public static void EnableMouseInput()
    {
        var handle = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(handle, out var mode);
        mode |= ENABLE_MOUSE_INPUT;
        mode &= ~ENABLE_QUICK_EDIT_MODE; //关闭快速编辑
        SetConsoleMode(handle, mode);
    }
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "ReadConsoleInputW")]
    public static extern bool ReadConsoleInput(
    IntPtr hConsoleInput,
    [Out] INPUT_RECORD[] lpBuffer,
    uint nLength,
    out uint lpNumberOfEventsRead);
    public enum InputRecordEventType : uint
    {
        KEY_EVENT = 0x1,
        MOUSE_EVENT = 0x2,
        WINDOW_BUFFER_SIZE_EVENT = 0x4,
        MENU_EVENT = 0x8,
        FOCUS_EVENT = 0x10,
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct INPUT_RECORD
    {
        [FieldOffset(0)]
        public InputRecordEventType EventType;
        [FieldOffset(4)]
        public KEY_EVENT_RECORD KeyEvent;
        [FieldOffset(4)]
        public MOUSE_EVENT_RECORD MouseEvent;
        [FieldOffset(4)]
        public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
        [FieldOffset(4)]
        public MENU_EVENT_RECORD MenuEvent;
        [FieldOffset(4)]
        public FOCUS_EVENT_RECORD FocusEvent;
    };
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct KEY_EVENT_RECORD
    {
        [FieldOffset(0), MarshalAs(UnmanagedType.Bool)]
        public bool bKeyDown;
        [FieldOffset(4), MarshalAs(UnmanagedType.U2)]
        public ushort wRepeatCount;
        // ConsoleKey
        [FieldOffset(6), MarshalAs(UnmanagedType.U2)]
        public ushort wVirtualKeyCode;
        [FieldOffset(8), MarshalAs(UnmanagedType.U2)]
        public ushort wVirtualScanCode;
        [FieldOffset(10)]
        public char UnicodeChar;
        [FieldOffset(12), MarshalAs(UnmanagedType.U4)]
        public ControlKeyState dwControlKeyState;
    }

    // dwControlKeyState bitmask
    [Flags]
    public enum ControlKeyState
    {
        RIGHT_ALT_PRESSED = 0x1,
        LEFT_ALT_PRESSED = 0x2,
        RIGHT_CTRL_PRESSED = 0x4,
        LEFT_CTRL_PRESSED = 0x8,
        SHIFT_PRESSED = 0x10,
        NUMLOCK_ON = 0x20,
        SCROLLLOCK_ON = 0x40,
        CAPSLOCK_ON = 0x80,
        ENHANCED_KEY = 0x100
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSE_EVENT_RECORD
    {
        public COORD dwMousePosition;
        public MouseButtonState dwButtonState;
        public short MouseDelta;
        public ControlKeyState dwControlKeyState;
        public MouseEventFlags dwEventFlags;
    }

    [Flags]
    public enum MouseButtonState : short
    {
        FROM_LEFT_1ST_BUTTON_PRESSED = 0x1,
        RIGHTMOST_BUTTON_PRESSED = 0x2,
        FROM_LEFT_2ND_BUTTON_PRESSED = 0x4,
        FROM_LEFT_3RD_BUTTON_PRESSED = 0x8,
        FROM_LEFT_4TH_BUTTON_PRESSED = 0x10
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct COORD
    {
        public short X;
        public short Y;

        public COORD(short X, short Y)
        {
            this.X = X;
            this.Y = Y;
        }
    };
    [Flags]
    public enum MouseEventFlags
    {
        MOUSE_MOVED = 0x1,
        DOUBLE_CLICK = 0x2,
        MOUSE_WHEELED = 0x4,
        MOUSE_HWHEELED = 0x8
    }
    public struct WINDOW_BUFFER_SIZE_RECORD
    {
        public COORD dwSize;

        public WINDOW_BUFFER_SIZE_RECORD(short x, short y)
        {
            dwSize = new COORD(x, y);
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct MENU_EVENT_RECORD
    {
        public uint dwCommandId;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct FOCUS_EVENT_RECORD
    {
        public uint bSetFocus;
    }
}


标签:ReadConsoleInput,C#,public,RECORD,uint,注意,FieldOffset,EVENT,PRESSED
From: https://blog.51cto.com/u_14457770/6598275

相关文章

  • 十分钟搭建openstack平台
    十分钟搭建openstack平台https://www.rdoproject.org/install/packstack/先决条件在CentOSStream8/RHEL8上:network-scripts已弃用且默认未安装,因此需要显式安装。sudodnfinstallnetwork-scripts-y禁用firewalld和NetworkManagersudosystemctldisablefirewalldsudo......
  • pytest + yaml 框架 -42.支持 mock 功能
    前言前面已经通过代理实现了抓包自动生成yaml用例的功能,通过代理也可以实现mock功能。mock有2种场景:1.直接拦截发出去的请求,还未到达服务端,模拟自定义返回结果2.发出去的请求,服务端有反回,拦截返回的结果,篡改返回内容,模拟自己需要的数据拦截发出去的请求先看第一种场景:直接......
  • cpp: Sudoku
     /*****************************************************************//***\fileConsoleSudoku.cppc++14*\brief九宫独数填充游戏*fromhttps://github.com/vaithak/Sudoku-Generator*\authorgeovindu*\dateJuly2023************************......
  • FSCapture
    目录前言基础操作下载安装常用设置截图滚动截图录屏小技巧自动命名前言我本来用的是一款叫shareX的截图软件,用着也蛮好的!但因为最近要去考试,在考试的时候要大量截图,而且听说截图软件就是用的这一截FScapture,所以就来提前熟悉一下,感觉还不错,功能挺强大的!基础操作下载安装链接......
  • 未来的LibreOffice版本将允许导入和导出APNG图像
    导读文档基金会已经完成了其LibreOffice开源办公套件在2023年谷歌夏季代码(GSoC)中的项目选择,承诺将提供用户要求已久的新功能和改进。未来的LibreOffice版本将允许你导入和导出APNG(AnimatedPNG)图像,这是一种向后兼容PNG图像格式的动画格式,支持比GIF图像更多的颜色和部分透......
  • 将ChatGPT变成Midjourney提示生成器
    已经有人总结过可以让ChatGPT作为Midjourney图像生成的模板。在本文中,我们将展示如何根据个人用例创建这些提示,这可以让ChatGPT生成的提示可控性更高。 https://avoid.overfit.cn/post/60d45f154b7943258f86f8bc7150e79b......
  • Docker容器镜像加速
    环境:CentOS7设置docker环境[root@Master~]#mkdir-p/etc/docker[root@Master~]#cd/etc/docker[root@Masterdocker]#vidaemon.json{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]}重启服务[root@Masterdocker]#systemctldaemon-rel......
  • 安装Docker容器(Linux系统)
    环境:CentOS7更新yum包[root@Master~]#yumupdateLoadedplugins:fastestmirrorDeterminingfastestmirrors*base:mirrors.aliyun.com*extras:mirrors.aliyun.com*updates:mirrors.aliyun.combase......
  • 【零基础学习C++】如何写一个C++类?
    个人主页:【......
  • nested exception is java.sql.SQLException: connection disabled
    标题:解决SpringBoot连接数据库出现"connectiondisabled"异常在使用SpringBoot连接数据库时,有时候会遇到"nestedexceptionisjava.sql.SQLException:connectiondisabled"异常。这个异常通常是由以下原因引起的:数据库连接配置错误:检查数据库连接的URL、用户名和密码是否正确配......