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);
}