public static extern int WriteConsoleInputW([NativeTypeName("HANDLE")] IntPtr hConsoleInput, [NativeTypeName("const INPUT_RECORD *")] INPUT_RECORD *lpBuffer, [NativeTypeName("DWORD")] uint nLength, [NativeTypeName("LPDWORD")] uint *lpNumberOfEventsWritten);
extern static bool WriteConsoleInput(IntPtr handle, INPUT_RECORD *buffer, int length, out int nread);
private static unsafe extern BOOL PeekConsoleInput(IntPtr hConsoleInput, INPUT_RECORD *lpBuffer, uint nLength, uint *lpNumberOfEventsRead);
public static extern BOOL PeekConsoleInputW(HANDLE hConsoleInput, [NativeTypeName("PINPUT_RECORD")] INPUT_RECORD *lpBuffer, [NativeTypeName("DWORD")] uint nLength, [NativeTypeName("LPDWORD")] uint *lpNumberOfEventsRead);
public WindowsNativeConsoleProvider() { _threadToken = new CancellationTokenSource(); _buffer = (CHAR_INFO *)Marshal.AllocHGlobal(BufferSize * BufferSize * CHAR_INFO.SizeOf).ToPointer(); _buffer2 = (CHAR_INFO *)Marshal.AllocHGlobal(BufferSize * BufferSize * CHAR_INFO.SizeOf).ToPointer(); _stdin = GetStdHandle(-10); _stdout = GetStdHandle(-11); { var info = new CONSOLE_SCREEN_BUFFER_INFO(); GetConsoleScreenBufferInfo(_stdout, ref info); WindowWidth = info.Window.Right - info.Window.Left + 1; WindowHeight = info.Window.Bottom - info.Window.Top + 1; _prevBuf = info.Size; SetConsoleScreenBufferSize(_stdout, new COORD { X = (short)WindowWidth, Y = (short)WindowHeight }); } new Thread(() => // window size monitor { while (!_threadToken.IsCancellationRequested) { Thread.Sleep(16); var info = new CONSOLE_SCREEN_BUFFER_INFO(); GetConsoleScreenBufferInfo(_stdout, ref info); int nw = info.Window.Right - info.Window.Left + 1, nh = info.Window.Bottom - info.Window.Top + 1; if (nw < 0) { nw = WindowWidth; } if (nh < 0) { nh = WindowHeight; // fukken winapi bugs } if (nw == WindowWidth && nh == WindowHeight) { continue; } var pw = WindowWidth; var ph = WindowHeight; _resizeFlag = true; WindowWidth = nw; WindowHeight = nh; SetConsoleScreenBufferSize(_stdout, new COORD { X = (short)WindowWidth, Y = (short)WindowHeight }); try { SizeChanged?.Invoke(this, new SizeChangedEventArgs(new Size(pw, ph), new Size(nw, nh))); } catch { /* Do not care if subscriber f****d up */ } //Refresh(); } }) { Priority = ThreadPriority.Lowest }.Start(); _keyboardThread = new Thread(() => // keyboard monitor { INPUT_RECORD *charBuf = stackalloc INPUT_RECORD[1]; var ptr = new IntPtr(charBuf); var sizeOf = Marshal.SizeOf(typeof(INPUT_RECORD)); while (!_threadToken.IsCancellationRequested) { try { uint nchars = 0; Memset(ptr, 0, sizeOf); ReadConsoleInputW(_stdin, ptr, 1, ref nchars); if (charBuf->EventType == 1 && nchars == 1 && charBuf->KeyEvent.KeyDown) { KeyPressed?.Invoke( this, new KeyPressedEventArgs(new ConsoleKeyInfo( charBuf->KeyEvent.Char, (ConsoleKey)charBuf->KeyEvent.KeyCode, (charBuf->KeyEvent.ControlKeyState & 0x10) > 0, (charBuf->KeyEvent.ControlKeyState & 0x03) > 0, (charBuf->KeyEvent.ControlKeyState & 0x0c) > 0 ))); } } catch { } } }); _keyboardThread.Start(); }
public static extern int ReadConsoleInputW([NativeTypeName("HANDLE")] IntPtr hConsoleInput, [NativeTypeName("PINPUT_RECORD")] INPUT_RECORD *lpBuffer, [NativeTypeName("DWORD")] uint nLength, [NativeTypeName("LPDWORD")] uint *lpNumberOfEventsRead);