Надо сделать скриншот отдельного окна на экране. Допустим калькулятора. c#
Ответ
К сожалению, я не смог найти решение совсем без P/Invoke. Вы должны найти нужный процесс (обычно он у вас и так есть, раз вы за ним следите), его окно (например, у класса Process можно опросить MainWindowHandle), и у этого окна взять его координаты на экране. Для этого придётся вызывать WinAPI-функцию GetWindowRect
using System.Drawing;
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
}
Скопировать кусок экрана можно при помощи функции Graphics.CopyFromScreen, которая доступна в WinForms. Если у вас не WinForms-приложение, придётся подключить System.Drawing.dll
Получаем такой вот код:
var process = Process.GetProcessesByName(тут имя процесса).FirstOrDefault();
// не забудьте поверку ошибок: вдруг у вас не нашлось ни одного процесса?
GetWindowRect(process.MainWindowHandle, out var rect);
using (var image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top))
{
using (var graphics = Graphics.FromImage(image))
graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, image.Size);
// тут у вас есть картинка, вы можете, например, сохранить её
image.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png);
}
У меня получился вот такой скриншот окна Visual Studio:
Недостатки метода:
окно должно быть на переднем плане, иначе вы получите перекрытые части
могут быть проблемы с Aero-интерфейсом (вот тут решение, которое умеет бороться с этой проблемой, но я не проверял)
Обновление:
Я нашёл вот тут решение, которое обходит первую проблему, то есть, умеет делать снимок окна, не находящегося на переднем плане. Для этого мы должны использовать ещё одну WinAPI-функцию PrintWindow. Вот улучшенный код:
using System.Drawing;
using System.Drawing.Imaging;
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[DllImport("user32.dll")]
static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
}
var process = Process.GetProcessesByName(тут имя процесса).FirstOrDefault();
// не забудьте поверку ошибок: вдруг у вас не нашлось ни одного процесса?
var hwnd = process.MainWindowHandle;
GetWindowRect(hwnd, out var rect);
using (var image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top))
{
using (var graphics = Graphics.FromImage(image))
{
var hdcBitmap = graphics.GetHdc();
PrintWindow(hwnd, hdcBitmap, 0);
graphics.ReleaseHdc(hdcBitmap);
}
// тут у вас есть картинка, вы можете, например, сохранить её
image.Save(imagePath, ImageFormat.Png);
}
Комментариев нет:
Отправить комментарий