Interop.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace ConFrames
  8. {
  9. public class Interop
  10. {
  11. [DllImport("kernel32.dll", SetLastError = true)]
  12. public static extern IntPtr GetStdHandle(int nStdHandle);
  13. public const int STD_OUTPUT_HANDLE = -11;
  14. public const int STD_INPUT_HANDLE = -10;
  15. public const int STD_ERROR_HANDLE = -12;
  16. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  17. public static extern bool WriteConsoleOutput(
  18. IntPtr hConsoleOutput,
  19. CharInfo[] lpBuffer,
  20. Coord dwBufferSize,
  21. Coord dwBufferCoord,
  22. ref SmallRect lpWriteRegion);
  23. [DllImport("Kernel32.dll", SetLastError = true)]
  24. public static extern IntPtr CreateConsoleScreenBuffer(
  25. uint dwDesiredAccess,
  26. uint dwShareMode,
  27. IntPtr secutiryAttributes,
  28. UInt32 flags,
  29. IntPtr screenBufferData
  30. );
  31. [DllImport("kernel32.dll", SetLastError = true)]
  32. public static extern bool SetConsoleScreenBufferSize(IntPtr hConsoleOutput, Coord dwSize);
  33. [DllImport("kernel32.dll", SetLastError = true)]
  34. public static extern bool SetConsoleActiveScreenBuffer(IntPtr hConsoleOutput);
  35. [DllImport("kernel32.dll", SetLastError = true)]
  36. public static extern bool SetConsoleCursorPosition(IntPtr hConsoleOutput, Coord dwCursorPosition);
  37. [DllImport("kernel32.dll", SetLastError = true)]
  38. public static extern bool SetConsoleCursorInfo(IntPtr hConsoleOutput, ref CONSOLE_CURSOR_INFO info);
  39. [DllImport("kernel32.dll", SetLastError = true)]
  40. public static extern bool GetConsoleCursorInfo(IntPtr hConsoleOutput, out CONSOLE_CURSOR_INFO info);
  41. [DllImport("kernel32.dll", SetLastError = true)]
  42. public static extern bool SetConsoleWindowInfo(IntPtr hConsoleOutput, bool absolute, ref SmallRect rect);
  43. [DllImport("kernel32.dll", SetLastError = true)]
  44. public static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO info);
  45. [DllImport("kernel32.dll", SetLastError = true)]
  46. public static extern IntPtr GetConsoleWindow();
  47. [DllImport("user32.dll")]
  48. [return: MarshalAs(UnmanagedType.Bool)]
  49. public static extern bool SetForegroundWindow(IntPtr hWnd);
  50. [DllImport("user32.dll")]
  51. public static extern IntPtr GetForegroundWindow();
  52. [DllImport("user32.dll")]
  53. public static extern IntPtr GetActiveWindow();
  54. public static bool SetConsoleCursorVisible(IntPtr hConsole, bool visible)
  55. {
  56. CONSOLE_CURSOR_INFO info;
  57. if (!GetConsoleCursorInfo(hConsole, out info))
  58. return false;
  59. if (info.bVisible != visible)
  60. {
  61. info.bVisible = visible;
  62. return SetConsoleCursorInfo(hConsole, ref info);
  63. }
  64. return true;
  65. }
  66. [StructLayout(LayoutKind.Sequential)]
  67. public struct CONSOLE_CURSOR_INFO
  68. {
  69. public uint dwSize;
  70. public bool bVisible;
  71. };
  72. [StructLayout(LayoutKind.Sequential)]
  73. public struct CONSOLE_SCREEN_BUFFER_INFO
  74. {
  75. public Coord dwSize;
  76. public Coord dwCursorPosition;
  77. public ushort wAttributes;
  78. public SmallRect srWindow;
  79. public Coord dwMaximumWindowSize;
  80. }
  81. [StructLayout(LayoutKind.Sequential)]
  82. public struct CONSOLE_SCREEN_BUFFER_INFOEX
  83. {
  84. public int cbSize;
  85. public Coord dwSize;
  86. public Coord dwCursorPosition;
  87. public ushort wAttributes;
  88. public SmallRect srWindow;
  89. public Coord dwMaximumWindowSize;
  90. public ushort wPopupAttributes;
  91. public bool bFullscreenSupported;
  92. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  93. public uint[] ColorTable;
  94. }
  95. [DllImport("kernel32.dll", SetLastError = true)]
  96. public static extern bool GetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX info);
  97. [DllImport("kernel32.dll", SetLastError = true)]
  98. public static extern bool SetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX info);
  99. [DllImport("kernel32.dll", SetLastError = true)]
  100. public static extern Coord GetLargestConsoleWindowSize(IntPtr hConsoleOutput);
  101. public static void SetBufferAndScreenSize(IntPtr hConsoleOutput, short x, short y)
  102. {
  103. var largestSize = GetLargestConsoleWindowSize(hConsoleOutput);
  104. if (x > largestSize.X || y > largestSize.Y)
  105. throw new ArgumentException(string.Format("requested size is too big (max = {0} x {1})", largestSize.X, largestSize.Y));
  106. CONSOLE_SCREEN_BUFFER_INFO bi;
  107. if (!GetConsoleScreenBufferInfo(hConsoleOutput, out bi))
  108. throw new InvalidOperationException("GetConsoleScreenBufferInfo failed");
  109. Coord windowSize = new Coord((short)(bi.srWindow.Width + 1), (short)(bi.srWindow.Height + 1));
  110. if (windowSize.X > x || windowSize.Y > y)
  111. {
  112. var shrink = new SmallRect();
  113. shrink.Right = (short)(x < windowSize.X ? x - 1 : windowSize.X - 1);
  114. shrink.Bottom = (short)(y < windowSize.Y ? y - 1 : windowSize.Y - 1);
  115. if (!SetConsoleWindowInfo(hConsoleOutput, true, ref shrink))
  116. throw new InvalidOperationException("Failed to shrink window");
  117. }
  118. if (!SetConsoleScreenBufferSize(hConsoleOutput, new Coord(x, y)))
  119. throw new InvalidOperationException("Failed to resize buffer");
  120. var info = new SmallRect();
  121. info.Right = (short)(x - 1);
  122. info.Bottom = (short)(y - 1);
  123. if (!SetConsoleWindowInfo(hConsoleOutput, true, ref info))
  124. throw new InvalidOperationException("Failed to resize window");
  125. CONSOLE_SCREEN_BUFFER_INFO cbi;
  126. GetConsoleScreenBufferInfo(hConsoleOutput, out cbi);
  127. }
  128. public const uint CONSOLE_TEXTMODE_BUFFER = 0x00000001;
  129. public const uint GENERIC_READ = 0x80000000;
  130. public const uint GENERIC_WRITE = 0x40000000;
  131. public const uint GENERIC_READWRITE = GENERIC_READ | GENERIC_WRITE;
  132. [StructLayout(LayoutKind.Sequential)]
  133. public struct Coord
  134. {
  135. public short X;
  136. public short Y;
  137. public Coord(short X, short Y)
  138. {
  139. this.X = X;
  140. this.Y = Y;
  141. }
  142. };
  143. [StructLayout(LayoutKind.Sequential)]
  144. public struct SmallRect
  145. {
  146. public short Left;
  147. public short Top;
  148. public short Right;
  149. public short Bottom;
  150. public short Width { get { return (short)(Right - Left); } }
  151. public short Height { get { return (short)(Bottom - Top); } }
  152. }
  153. }
  154. }