lib-gui.ps1 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # GUI helpers for the PCL PoC demo VM.
  2. # ASCII only. Windows PowerShell 5.1 compatible.
  3. if (-not ('PclGui' -as [type])) {
  4. Add-Type -TypeDefinition @'
  5. using System;
  6. using System.Runtime.InteropServices;
  7. public class PclGui
  8. {
  9. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  10. public struct DEVMODE
  11. {
  12. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  13. public string dmDeviceName;
  14. public short dmSpecVersion;
  15. public short dmDriverVersion;
  16. public short dmSize;
  17. public short dmDriverExtra;
  18. public int dmFields;
  19. public int dmPositionX;
  20. public int dmPositionY;
  21. public int dmDisplayOrientation;
  22. public int dmDisplayFixedOutput;
  23. public short dmColor;
  24. public short dmDuplex;
  25. public short dmYResolution;
  26. public short dmTTOption;
  27. public short dmCollate;
  28. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  29. public string dmFormName;
  30. public short dmLogPixels;
  31. public int dmBitsPerPel;
  32. public int dmPelsWidth;
  33. public int dmPelsHeight;
  34. public int dmDisplayFlags;
  35. public int dmDisplayFrequency;
  36. public int dmICMMethod;
  37. public int dmICMIntent;
  38. public int dmMediaType;
  39. public int dmDitherType;
  40. public int dmReserved1;
  41. public int dmReserved2;
  42. public int dmPanningWidth;
  43. public int dmPanningHeight;
  44. }
  45. [DllImport("user32.dll", CharSet = CharSet.Ansi)]
  46. public static extern bool EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
  47. [DllImport("user32.dll")]
  48. public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
  49. [DllImport("user32.dll")]
  50. public static extern bool SetProcessDPIAware();
  51. [DllImport("user32.dll")]
  52. public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
  53. [DllImport("user32.dll")]
  54. public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
  55. [DllImport("kernel32.dll")]
  56. public static extern IntPtr GetConsoleWindow();
  57. [DllImport("kernel32.dll", SetLastError = true)]
  58. public static extern IntPtr GetStdHandle(int nStdHandle);
  59. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  60. public struct CONSOLE_FONT_INFO_EX
  61. {
  62. public uint cbSize;
  63. public uint nFont;
  64. public short dwFontSizeX;
  65. public short dwFontSizeY;
  66. public uint FontFamily;
  67. public uint FontWeight;
  68. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  69. public string FaceName;
  70. }
  71. [DllImport("kernel32.dll", SetLastError = true)]
  72. public static extern bool SetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool bMaximumWindow, ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx);
  73. public static string SetBestResolution()
  74. {
  75. int[][] prefs = new int[][]
  76. {
  77. new int[] { 1920, 1080 },
  78. new int[] { 1600, 900 },
  79. new int[] { 1366, 768 },
  80. new int[] { 1280, 720 },
  81. new int[] { 1024, 768 }
  82. };
  83. foreach (int[] pref in prefs)
  84. {
  85. DEVMODE found = new DEVMODE();
  86. found.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
  87. bool ok = false;
  88. for (int i = 0; EnumDisplaySettings(null, i, ref found); i++)
  89. {
  90. if (found.dmPelsWidth == pref[0] && found.dmPelsHeight == pref[1] && found.dmBitsPerPel == 32)
  91. {
  92. ok = true;
  93. break;
  94. }
  95. }
  96. if (!ok) continue;
  97. DEVMODE set = found;
  98. set.dmFields = 0x80000 | 0x100000 | 0x40000; // width, height, bits per pixel
  99. int r = ChangeDisplaySettings(ref set, 0x00000001); // CDS_UPDATEREGISTRY
  100. if (r == 0)
  101. {
  102. return pref[0].ToString() + "x" + pref[1].ToString();
  103. }
  104. }
  105. return "unchanged";
  106. }
  107. public static bool SetConsoleFont(int size)
  108. {
  109. IntPtr h = GetStdHandle(-11);
  110. if (h == IntPtr.Zero) return false;
  111. CONSOLE_FONT_INFO_EX f = new CONSOLE_FONT_INFO_EX();
  112. f.cbSize = (uint)Marshal.SizeOf(typeof(CONSOLE_FONT_INFO_EX));
  113. f.nFont = 0;
  114. f.dwFontSizeX = 0;
  115. f.dwFontSizeY = (short)size;
  116. f.FontFamily = 54;
  117. f.FontWeight = 400;
  118. f.FaceName = "Consolas";
  119. return SetCurrentConsoleFontEx(h, false, ref f);
  120. }
  121. public static void Move(IntPtr h, int x, int y, int w, int hgt)
  122. {
  123. if (h == IntPtr.Zero) return;
  124. ShowWindow(h, 9); // SW_RESTORE
  125. SetWindowPos(h, IntPtr.Zero, x, y, w, hgt, 0x0040); // SWP_SHOWWINDOW
  126. }
  127. }
  128. '@
  129. }
  130. function Set-ConsoleSize {
  131. param([int]$Columns, [int]$Rows)
  132. try {
  133. $buffer = New-Object System.Management.Automation.Host.Size([Math]::Max($Columns, 120), 600)
  134. $Host.UI.RawUI.BufferSize = $buffer
  135. } catch { }
  136. try {
  137. $window = New-Object System.Management.Automation.Host.Size($Columns, $Rows)
  138. $Host.UI.RawUI.WindowSize = $window
  139. } catch { }
  140. }