using System.Runtime.InteropServices; using System.Text; namespace Mir2Assistant.Common.Utils; /// /// 窗口工具类 /// public class WindowUtils { public static bool Enabled(IntPtr win) { return !GetStyles(win).Contains(WindowStyles.WS_DISABLED); } /// 表示指定的窗口 是否存在 /// 窗口地址 public static bool Exists(IntPtr win) { return GetProcessId(win) != 0; } /// /// 聚焦窗口 /// /// 句柄 /// public static bool FocuseWindow(IntPtr hWnd) { return SetForegroundWindow(hWnd); } public static Icon? GetAppIcon(IntPtr hwnd) { IntPtr iconHandle = SendMessage(hwnd, WM_GETICON, ICON_SMALL2, null); if (iconHandle == IntPtr.Zero) iconHandle = SendMessage(hwnd, WM_GETICON, ICON_SMALL, null); if (iconHandle == IntPtr.Zero) iconHandle = SendMessage(hwnd, WM_GETICON, ICON_BIG, null); if (iconHandle == IntPtr.Zero) iconHandle = GetClassLongPtr(hwnd, GCL_HICON); if (iconHandle == IntPtr.Zero) iconHandle = GetClassLongPtr(hwnd, GCL_HICONSM); if (iconHandle == IntPtr.Zero) return null; Icon icn = Icon.FromHandle(iconHandle); return icn; } public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { if (IntPtr.Size > 4) return GetClassLongPtr64(hWnd, nIndex); else return new IntPtr(GetClassLongPtr32(hWnd, nIndex)); } /// 返回指定窗口的客户区矩形 /// 窗口地址 public static Rectangle GetClientRect(IntPtr win) { MyRect rect = new MyRect(); GetClientRect(win, out rect); Rectangle result = new Rectangle(); POINT p = new POINT(0, 0); ClientToScreen(win, ref p); result.Location = p; result.Width = rect.Right - rect.Left; result.Height = rect.Bottom - rect.Top; return result; } /// 返回活动窗口的标题 public static string GetForegroundWindowText() { var win = GetForegroundWindow(); return GetWindowText(win); } /// 返回该窗口所属进程的ID /// 窗口地址 public static int GetProcessId(IntPtr win) { int id = 0; GetWindowThreadProcessId(win, ref id); return id; } public static List GetStyles(IntPtr win) { int style = GetWindowLong(win, GWL_STYLE); List result = new List(); foreach (var ws in Enum.GetValues(typeof(WindowStyles))) { if ((style & (uint)ws) != 0) result.Add((WindowStyles)ws); } return result; } public static string GetWindowCaption(IntPtr hWnd) { StringBuilder buff = new StringBuilder(256); //Get the text from the active window into the stringbuilder SendMessage(hWnd, WM_GETTEXT, 256, buff); return buff.ToString(); } /// 返回窗口类的名称 /// 窗口地址 public static string GetWindowClass(IntPtr win) { if (win == IntPtr.Zero) return ""; StringBuilder title = new StringBuilder(512); RealGetWindowClass(win, title, 512); return title.ToString().Trim(); } /// 返回指定窗口的矩形 /// 窗口地址 public static Rectangle GetWindowRect(IntPtr win) { MyRect rect = new MyRect(); GetWindowRect(win, out rect); Rectangle result = new Rectangle(); result.X = rect.Left; result.Y = rect.Top; result.Width = rect.Right - rect.Left; result.Height = rect.Bottom - rect.Top; return result; } /// 返回窗口标题 /// 窗口地址 public static string GetWindowText(IntPtr hWnd) { StringBuilder buff = new StringBuilder(256); GetWindowText(hWnd, buff, 256); return buff.ToString(); } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { this.X = x; this.Y = y; } public static implicit operator Point(POINT p) { return new Point(p.X, p.Y); } public static implicit operator POINT(Point p) { return new POINT(p.X, p.Y); } } [StructLayout(LayoutKind.Sequential)] public struct MyRect { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } #region User32.dll public const int GCL_HICON = -14; public const int GCL_HICONSM = -34; public const int GWL_STYLE = -16; public const int ICON_BIG = 1; public const int ICON_SMALL = 0; public const int ICON_SMALL2 = 2; public const int WM_GETICON = 0x7F; public const int WM_GETTEXT = 13; [Flags] public enum WindowStyles : uint { WS_OVERLAPPED = 0x00000000, WS_POPUP = 0x80000000, WS_CHILD = 0x40000000, WS_MINIMIZE = 0x20000000, WS_VISIBLE = 0x10000000, WS_DISABLED = 0x08000000, WS_CLIPSIBLINGS = 0x04000000, WS_CLIPCHILDREN = 0x02000000, WS_MAXIMIZE = 0x01000000, WS_BORDER = 0x00800000, WS_DLGFRAME = 0x00400000, WS_VSCROLL = 0x00200000, WS_HSCROLL = 0x00100000, WS_SYSMENU = 0x00080000, WS_THICKFRAME = 0x00040000, WS_GROUP = 0x00020000, WS_TABSTOP = 0x00010000, WS_MINIMIZEBOX = 0x00020000, WS_MAXIMIZEBOX = 0x00010000 } [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr win); [DllImport("user32.dll")] public static extern bool ClientToScreen(IntPtr win, ref POINT point); [DllImport("user32.dll", EntryPoint = "GetClassLong")] public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] public static extern bool GetClientRect(IntPtr hWnd, out MyRect lpRect); [DllImport("user32.dll", EntryPoint = "GetWindowLong")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr win, out MyRect rect); [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, ref int processId); [DllImport("user32.dll")] public static extern uint RealGetWindowClass(IntPtr win, StringBuilder pszType, uint cchType); [DllImport("user32.dll")] public static extern bool ScreenToClient(IntPtr win, ref POINT point); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder? lParam); /// /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。 /// 系统给创建前台窗口的线程分配的权限稍高于其他线程。 /// /// 将被激活并被调入前台的窗口句柄 /// 如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零 [DllImport("User32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); #endregion User32.dll [DllImport("kernel32.dll")] public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, int size, IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll", SetLastError = true)] public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); [DllImport("kernel32.dll", EntryPoint = "CloseHandle")] public static extern IntPtr CloseHandle(IntPtr hObject); [DllImport("Kernel32.dll")] public static extern System.Int32 VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, int flAllocationType); }