conjure-os-overlay/Overlay/WindowUtils.cs
2025-10-10 18:26:49 -04:00

89 lines
2.6 KiB
C#

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Conjure.Arcade.Overlay
{
public static class WindowUtils
{
[DllImport("kernel32.dll")]
private static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
private static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
private static extern uint ResumeThread(IntPtr hThread);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
[Flags]
private enum ThreadAccess : int
{
SUSPEND_RESUME = 0x0002
}
[DllImport("user32.dll")]
private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public static bool GetWindowBounds(IntPtr handle, out Rect rect)
{
rect = new Rect();
return GetWindowRect(handle, ref rect) != IntPtr.Zero;
}
public static Process? FindProcess(string processName)
{
var processes = Process.GetProcessesByName(processName);
return processes.Length > 0 ? processes[0] : null;
}
public static void SuspendProcess(Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var threadHandle = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (threadHandle != IntPtr.Zero)
{
try
{
SuspendThread(threadHandle);
}
finally
{
CloseHandle(threadHandle);
}
}
}
}
public static void ResumeProcess(Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var threadHandle = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (threadHandle != IntPtr.Zero)
{
try
{
ResumeThread(threadHandle);
}
finally
{
CloseHandle(threadHandle);
}
}
}
}
}
}