分类
标签
.NET 9008 adb android apt asp.net ASP.NET Core audio bug C c++ C++ chrome cmd csharp CSharp css css3 debian debug dotnet dotnet Framework dpkg GDI&GDI+ gdi&gdi+ golang graphics html html5 http java javascript json kali linux linux mci microsoft minimap MSBuild mysql OpenCV PInvoke powershell python QQ rust shell speex sql tutorial ubuntu ui unity vb.net visual studio Visual Studio web Web win32 winapi windows winform WinForm wpf WPF xaml xfce 列表 刷机 前端 加密 反射 反编译 可视化 图像处理 多线程 字符串 安卓 实例 局域网 幻影坦克 库 开发语言 异步 微信 手册 手机 接口 摘要 救砖 数字签名 数字证书 数字音频 数据库 桌面程序 游戏 游戏引擎 源码 爬虫 玩游戏 电脑硬件 笔记 算法 类库 线性代数 编程语言 网络 脚本语言 计算机图形学 计算机基础 设计模式 语音编解码 运维 进制 面向对象编程 音频 音频编码解码
516 字
3 分钟
[C#] 使用 ReadConsoleInput 所需要注意的问题.
如果要使用鼠标输入, 那么需要:
- 启用鼠标输入, 只有启用之后, 才能接收到鼠标事件
- 关闭控制台的快速编辑模式, 很多人的控制台都启用了快速编辑模式, 它会导致鼠标输入无效
任何情况下, 都需要:
- 不使用除 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;
}
}
[C#] 使用 ReadConsoleInput 所需要注意的问题.
https://slimenull.com/posts/20230627205243/