Files
IPClab1/Services/WindowInteractionService.cs
2026-09-24 21:12:12 +03:00

111 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using IPClab1.Enums;
namespace IPClab1.Services;
public partial class WindowInteractionService
{
private const uint WM_MOUSEMOVE = 0x0200;
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
private const uint WM_SETTEXT = 0x000C;
private const uint WM_CLOSE = 0x0010;
private const uint WM_SYSCOMMAND = 0x0112;
private const int SC_MINIMIZE = 0xF020;
private const int SC_MAXIMIZE = 0xF030;
private const int SC_RESTORE = 0xF120;
[LibraryImport("user32.dll", EntryPoint = "SendMessageW", StringMarshalling = StringMarshalling.Utf16)]
private static partial IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);
[LibraryImport("user32.dll", EntryPoint = "PostMessageW")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[LibraryImport("user32.dll", EntryPoint = "GetClassNameW", SetLastError = true)]
private static partial int GetClassName(IntPtr hWnd, [Out] char[] lpClassName, int nMaxCount);
[LibraryImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[LibraryImport("user32.dll")]
private static partial IntPtr GetParent(IntPtr hWnd);
public void SimulateClick(IntPtr hwnd, int x, int y)
{
IntPtr lParam = (IntPtr)((y << 16) | (x & 0xFFFF));
PostMessage(hwnd, WM_MOUSEMOVE, IntPtr.Zero, lParam);
PostMessage(hwnd, WM_LBUTTONDOWN, (IntPtr)1, lParam);
PostMessage(hwnd, WM_LBUTTONUP, IntPtr.Zero, lParam);
}
public void SetText(IntPtr hwnd, string text)
{
if (string.IsNullOrEmpty(text)) return;
SendMessage(hwnd, WM_SETTEXT, IntPtr.Zero, text);
}
public void SetWindowState(IntPtr hwnd, WindowState state)
{
IntPtr wParam = state switch
{
WindowState.Minimize => (IntPtr)SC_MINIMIZE,
WindowState.Maximize => (IntPtr)SC_MAXIMIZE,
WindowState.Restore => (IntPtr)SC_RESTORE,
_ => IntPtr.Zero
};
if (wParam != IntPtr.Zero)
{
PostMessage(hwnd, WM_SYSCOMMAND, wParam, IntPtr.Zero);
}
}
public void CloseWindow(IntPtr hwnd)
{
PostMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
public (int, int) GetWindowSize(IntPtr hwnd)
{
GetWindowRect(hwnd, out RECT rect);
return (rect.Width, rect.Height);
}
public string GetWindowDetails(IntPtr hwnd)
{
char[] classNameBuffer = new char[256];
int length = GetClassName(hwnd, classNameBuffer, classNameBuffer.Length);
string className = length > 0 ? new string(classNameBuffer, 0, length) : string.Empty;
GetWindowRect(hwnd, out RECT rect);
IntPtr parentHWnd = GetParent(hwnd);
bool isChild = (parentHWnd != IntPtr.Zero);
return @$"Класс окна: {className}
Положение: (x, y) = ({rect.Left}, {rect.Top})
Размер: (w, h) = ({rect.Width}, {rect.Height})
Является дочерним: {(isChild ? "да" : "нет")}{(isChild ? $"\nРодительское окно: 0x{parentHWnd.ToInt64():X}" : "")}";
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public int Width => Right - Left;
public int Height => Bottom - Top;
}
}