156 lines
4.9 KiB
C#
156 lines
4.9 KiB
C#
using BotSharp.Abstraction.ComputerUse.MLTasks;
|
|
using System.Runtime.InteropServices;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
|
|
namespace BotSharp.Plugin.OsDriver;
|
|
|
|
public class ScreenshotWinOS : IScreenshot
|
|
{
|
|
// Define RECT structure
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT
|
|
{
|
|
public int Left, Top, Right, Bottom;
|
|
}
|
|
|
|
// Define MONITORINFO structure
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct MONITORINFO
|
|
{
|
|
public uint cbSize;
|
|
public RECT rcMonitor;
|
|
public RECT rcWork;
|
|
public uint dwFlags;
|
|
}
|
|
|
|
// Delegate for monitor enumeration callback
|
|
private delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);
|
|
|
|
// P/Invoke declarations
|
|
[DllImport("user32.dll")]
|
|
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip,
|
|
MonitorEnumDelegate lpfnEnum, IntPtr dwData);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern IntPtr CreateDC(string lpszDriver, string lpszDevice,
|
|
string lpszOutput, IntPtr lpInitData);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth,
|
|
int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, CopyPixelOperation dwRop);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern bool DeleteDC(IntPtr hdc);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern bool DeleteObject(IntPtr hObject);
|
|
|
|
// Class to hold monitor information
|
|
public class MonitorInfo
|
|
{
|
|
public IntPtr MonitorHandle;
|
|
public RECT MonitorArea;
|
|
}
|
|
|
|
public byte[] CaptureScreen(int displayId)
|
|
{
|
|
// Get all monitors
|
|
var monitors = GetMonitors();
|
|
|
|
// Validate the screen index
|
|
if (displayId < 0 || displayId >= monitors.Count)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(displayId), "Invalid screen index.");
|
|
}
|
|
|
|
var monitor = monitors[displayId];
|
|
using var bitmap = CaptureMonitor(monitor);
|
|
|
|
using var ms = new System.IO.MemoryStream();
|
|
bitmap.Save(ms, ImageFormat.Jpeg);
|
|
|
|
return ms.ToArray();
|
|
}
|
|
|
|
// Method to capture a specific monitor
|
|
public static Bitmap CaptureMonitor(MonitorInfo monitor)
|
|
{
|
|
int width = monitor.MonitorArea.Right - monitor.MonitorArea.Left;
|
|
int height = monitor.MonitorArea.Bottom - monitor.MonitorArea.Top;
|
|
|
|
IntPtr hdcSrc = CreateDC("DISPLAY", null, null, IntPtr.Zero);
|
|
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
|
|
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height);
|
|
IntPtr hOld = SelectObject(hdcDest, hBitmap);
|
|
|
|
bool success = BitBlt(hdcDest, 0, 0, width, height, hdcSrc,
|
|
monitor.MonitorArea.Left, monitor.MonitorArea.Top, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
|
|
|
|
Bitmap bmp = null;
|
|
|
|
if (success)
|
|
{
|
|
bmp = Image.FromHbitmap(hBitmap);
|
|
}
|
|
|
|
// Clean up
|
|
SelectObject(hdcDest, hOld);
|
|
DeleteObject(hBitmap);
|
|
DeleteDC(hdcDest);
|
|
DeleteDC(hdcSrc);
|
|
|
|
return bmp;
|
|
}
|
|
|
|
public (int x, int y) GetScreenSize(int screenIndex)
|
|
{
|
|
// Get all monitors
|
|
var monitors = GetMonitors();
|
|
|
|
// Validate the screen index
|
|
if (screenIndex < 0 || screenIndex >= monitors.Count)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(screenIndex), "Invalid screen index.");
|
|
}
|
|
|
|
var monitor = monitors[screenIndex];
|
|
return (monitor.MonitorArea.Right - monitor.MonitorArea.Left, monitor.MonitorArea.Bottom - monitor.MonitorArea.Top);
|
|
}
|
|
|
|
// Method to get all connected monitors
|
|
public static List<MonitorInfo> GetMonitors()
|
|
{
|
|
var monitors = new List<MonitorInfo>();
|
|
|
|
bool Callback(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData)
|
|
{
|
|
var mi = new MONITORINFO { cbSize = (uint)Marshal.SizeOf(typeof(MONITORINFO)) };
|
|
if (GetMonitorInfo(hMonitor, ref mi))
|
|
{
|
|
monitors.Add(new MonitorInfo
|
|
{
|
|
MonitorHandle = hMonitor,
|
|
MonitorArea = mi.rcMonitor
|
|
});
|
|
}
|
|
return true; // Continue enumeration
|
|
}
|
|
|
|
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, Callback, IntPtr.Zero);
|
|
return monitors;
|
|
}
|
|
}
|