WindowUtils.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. using System.Runtime.InteropServices;
  2. using System.Text;
  3. namespace Mir2Assistant.Common.Utils;
  4. /// <summary>
  5. /// 窗口工具类
  6. /// </summary>
  7. public class WindowUtils
  8. {
  9. public static bool Enabled(IntPtr win)
  10. {
  11. return !GetStyles(win).Contains(WindowStyles.WS_DISABLED);
  12. }
  13. /// <summary> 表示指定的窗口 </summary> 是否存在
  14. /// <param name = "win">窗口地址</param>
  15. public static bool Exists(IntPtr win)
  16. {
  17. return GetProcessId(win) != 0;
  18. }
  19. /// <summary>
  20. /// 聚焦窗口
  21. /// </summary>
  22. /// <param name="hWnd">句柄</param>
  23. /// <returns></returns>
  24. public static bool FocuseWindow(IntPtr hWnd)
  25. {
  26. return SetForegroundWindow(hWnd);
  27. }
  28. public static Icon? GetAppIcon(IntPtr hwnd)
  29. {
  30. IntPtr iconHandle = SendMessage(hwnd, WM_GETICON, ICON_SMALL2, null);
  31. if (iconHandle == IntPtr.Zero)
  32. iconHandle = SendMessage(hwnd, WM_GETICON, ICON_SMALL, null);
  33. if (iconHandle == IntPtr.Zero)
  34. iconHandle = SendMessage(hwnd, WM_GETICON, ICON_BIG, null);
  35. if (iconHandle == IntPtr.Zero)
  36. iconHandle = GetClassLongPtr(hwnd, GCL_HICON);
  37. if (iconHandle == IntPtr.Zero)
  38. iconHandle = GetClassLongPtr(hwnd, GCL_HICONSM);
  39. if (iconHandle == IntPtr.Zero)
  40. return null;
  41. Icon icn = Icon.FromHandle(iconHandle);
  42. return icn;
  43. }
  44. public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex)
  45. {
  46. if (IntPtr.Size > 4) return GetClassLongPtr64(hWnd, nIndex);
  47. else return new IntPtr(GetClassLongPtr32(hWnd, nIndex));
  48. }
  49. /// <summary> 返回指定窗口的客户区矩形</summary>
  50. /// <param name = "win">窗口地址</param>
  51. public static Rectangle GetClientRect(IntPtr win)
  52. {
  53. MyRect rect = new MyRect();
  54. GetClientRect(win, out rect);
  55. Rectangle result = new Rectangle();
  56. POINT p = new POINT(0, 0);
  57. ClientToScreen(win, ref p);
  58. result.Location = p;
  59. result.Width = rect.Right - rect.Left;
  60. result.Height = rect.Bottom - rect.Top;
  61. return result;
  62. }
  63. /// <summary> 返回活动窗口的标题 </summary>
  64. public static string GetForegroundWindowText()
  65. {
  66. var win = GetForegroundWindow();
  67. return GetWindowText(win);
  68. }
  69. /// <summary> 返回该窗口所属进程的ID </summary>
  70. /// <param name = "win">窗口地址</param>
  71. public static int GetProcessId(IntPtr win)
  72. {
  73. int id = 0;
  74. GetWindowThreadProcessId(win, ref id);
  75. return id;
  76. }
  77. public static List<WindowStyles> GetStyles(IntPtr win)
  78. {
  79. int style = GetWindowLong(win, GWL_STYLE);
  80. List<WindowStyles> result = new List<WindowStyles>();
  81. foreach (var ws in Enum.GetValues(typeof(WindowStyles)))
  82. {
  83. if ((style & (uint)ws) != 0) result.Add((WindowStyles)ws);
  84. }
  85. return result;
  86. }
  87. public static string GetWindowCaption(IntPtr hWnd)
  88. {
  89. StringBuilder buff = new StringBuilder(256);
  90. //Get the text from the active window into the stringbuilder
  91. SendMessage(hWnd, WM_GETTEXT, 256, buff);
  92. return buff.ToString();
  93. }
  94. /// <summary> 返回窗口类的名称</summary>
  95. /// <param name = "win">窗口地址</param>
  96. public static string GetWindowClass(IntPtr win)
  97. {
  98. if (win == IntPtr.Zero) return "";
  99. StringBuilder title = new StringBuilder(512);
  100. RealGetWindowClass(win, title, 512);
  101. return title.ToString().Trim();
  102. }
  103. /// <summary> 返回指定窗口的矩形</summary>
  104. /// <param name = "win">窗口地址</param>
  105. public static Rectangle GetWindowRect(IntPtr win)
  106. {
  107. MyRect rect = new MyRect();
  108. GetWindowRect(win, out rect);
  109. Rectangle result = new Rectangle();
  110. result.X = rect.Left;
  111. result.Y = rect.Top;
  112. result.Width = rect.Right - rect.Left;
  113. result.Height = rect.Bottom - rect.Top;
  114. return result;
  115. }
  116. /// <summary> 返回窗口标题</summary>
  117. /// <param name = "hWnd">窗口地址</param>
  118. public static string GetWindowText(IntPtr hWnd)
  119. {
  120. StringBuilder buff = new StringBuilder(256);
  121. GetWindowText(hWnd, buff, 256);
  122. return buff.ToString();
  123. }
  124. [StructLayout(LayoutKind.Sequential)]
  125. public struct POINT
  126. {
  127. public int X;
  128. public int Y;
  129. public POINT(int x, int y)
  130. {
  131. this.X = x;
  132. this.Y = y;
  133. }
  134. public static implicit operator Point(POINT p)
  135. {
  136. return new Point(p.X, p.Y);
  137. }
  138. public static implicit operator POINT(Point p)
  139. {
  140. return new POINT(p.X, p.Y);
  141. }
  142. }
  143. [StructLayout(LayoutKind.Sequential)]
  144. public struct MyRect
  145. {
  146. public int Left; // x position of upper-left corner
  147. public int Top; // y position of upper-left corner
  148. public int Right; // x position of lower-right corner
  149. public int Bottom; // y position of lower-right corner
  150. }
  151. #region User32.dll
  152. public const int GCL_HICON = -14;
  153. public const int GCL_HICONSM = -34;
  154. public const int GWL_STYLE = -16;
  155. public const int ICON_BIG = 1;
  156. public const int ICON_SMALL = 0;
  157. public const int ICON_SMALL2 = 2;
  158. public const int WM_GETICON = 0x7F;
  159. public const int WM_GETTEXT = 13;
  160. [Flags]
  161. public enum WindowStyles : uint
  162. {
  163. WS_OVERLAPPED = 0x00000000,
  164. WS_POPUP = 0x80000000,
  165. WS_CHILD = 0x40000000,
  166. WS_MINIMIZE = 0x20000000,
  167. WS_VISIBLE = 0x10000000,
  168. WS_DISABLED = 0x08000000,
  169. WS_CLIPSIBLINGS = 0x04000000,
  170. WS_CLIPCHILDREN = 0x02000000,
  171. WS_MAXIMIZE = 0x01000000,
  172. WS_BORDER = 0x00800000,
  173. WS_DLGFRAME = 0x00400000,
  174. WS_VSCROLL = 0x00200000,
  175. WS_HSCROLL = 0x00100000,
  176. WS_SYSMENU = 0x00080000,
  177. WS_THICKFRAME = 0x00040000,
  178. WS_GROUP = 0x00020000,
  179. WS_TABSTOP = 0x00010000,
  180. WS_MINIMIZEBOX = 0x00020000,
  181. WS_MAXIMIZEBOX = 0x00010000
  182. }
  183. [DllImport("user32.dll")]
  184. public static extern IntPtr GetForegroundWindow();
  185. [DllImport("user32.dll")]
  186. [return: MarshalAs(UnmanagedType.Bool)]
  187. public static extern bool IsWindowVisible(IntPtr win);
  188. [DllImport("user32.dll")]
  189. public static extern bool ClientToScreen(IntPtr win, ref POINT point);
  190. [DllImport("user32.dll", EntryPoint = "GetClassLong")]
  191. public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex);
  192. [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")]
  193. public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex);
  194. [DllImport("user32.dll")]
  195. public static extern bool GetClientRect(IntPtr hWnd, out MyRect lpRect);
  196. [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
  197. public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
  198. [DllImport("user32.dll")]
  199. [return: MarshalAs(UnmanagedType.Bool)]
  200. public static extern bool GetWindowRect(IntPtr win, out MyRect rect);
  201. [DllImport("user32.dll")]
  202. public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
  203. [DllImport("user32.dll")]
  204. public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, ref int processId);
  205. [DllImport("user32.dll")]
  206. public static extern uint RealGetWindowClass(IntPtr win, StringBuilder pszType, uint cchType);
  207. [DllImport("user32.dll")]
  208. public static extern bool ScreenToClient(IntPtr win, ref POINT point);
  209. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  210. public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder? lParam);
  211. /// <summary>
  212. /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
  213. /// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
  214. /// </summary>
  215. /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
  216. /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
  217. [DllImport("User32.dll")]
  218. public static extern bool SetForegroundWindow(IntPtr hWnd);
  219. #endregion User32.dll
  220. [DllImport("kernel32.dll")]
  221. public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, int size, IntPtr lpNumberOfBytesWritten);
  222. [DllImport("kernel32.dll")]
  223. public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
  224. [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
  225. public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
  226. [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
  227. public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);
  228. [DllImport("kernel32.dll")]
  229. public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
  230. [DllImport("kernel32.dll", SetLastError = true)]
  231. public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
  232. [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
  233. public static extern IntPtr CloseHandle(IntPtr hObject);
  234. [DllImport("Kernel32.dll")]
  235. public static extern System.Int32 VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, int flAllocationType);
  236. }