Как отмечается в комментариях, этот метод будет возвращать ClientArea
окна процесса, исключая Caption
(Title Bar
) только тогда, когда окно действительно имеет Caption
.Не все приложения это делают (в смысле WinForms ).
Кроме того, нет никаких гарантий того, что оно может работать с развернутым окном, отображаемым с использованием DirectX API.
В этом случае будет необходимодля реализации совершенно другого метода.
В любом случае, он должен корректно работать с отображаемым образцом.
Перегруженный основной метод принимает как имя процесса, так и идентификатор процесса.
Параметры :
string ProcessName
или int ProcessId
:
Укажитедружественное к процессу имя (отображаемое в диспетчере задач, без учета регистра) или идентификатор процесса (также доступен в диспетчере задач).
Его можно легко изменить, чтобы он также принимал заголовок окна.
bool ClientAreaOnly
:
Переключатель.Позволяет указать, хотите ли вы снимок экрана только для раздела ClientArea
или для всех границ Windows.
float Dpi
:
Вы можете определить разрешение в точках на дюйм:окончательный Bitmap
.
Пример использования :
- Снимок экрана главного окна процесса с именем [Some Process Name]
- Указывает толькорассмотрим ClientArea
(окно Caption
и Borders
будут исключены)
- указывает, что разрешение Bitmap
должно быть 120Dpi
- сохраняет Bitmap
в формате PNG
,с именем ScreenShot.png
, в [Some Path]
using (Bitmap bitmap = ProcessWindowScreenshot("[Some Process Name]", true, 120))
{
bitmap.Save(@"[Some Path]\ScreenShot.png", ImageFormat.Png);
}
Основные методы :
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
public Bitmap ProcessWindowScreenshot(string ProcessName, bool ClientAreaOnly, float Dpi) {
using (var process = Process.GetProcessesByName(ProcessName)
.FirstOrDefault(p => p.MainWindowHandle != IntPtr.Zero)) {
if (process == null) return null;
return GetProcessWindowScreenshot(GetProcessWindowRect(process.Id, ClientAreaOnly), Dpi);
}
}
public Bitmap ProcessWindowScreenshot(int ProcessId, bool ClientAreaOnly, float Dpi) {
return GetProcessWindowScreenshot(GetProcessWindowRect(ProcessId, ClientAreaOnly), Dpi);
}
private Bitmap GetProcessWindowScreenshot(Rectangle WindowArea, float Dpi)
{
using (Bitmap bitmap = new Bitmap(WindowArea.Width, WindowArea.Height, PixelFormat.Format32bppArgb))
{
if (Dpi < 96f) Dpi = 96f;
bitmap.SetResolution(Dpi, Dpi);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.High;
graphics.CopyFromScreen(WindowArea.Location, Point.Empty, WindowArea.Size, CopyPixelOperation.SourceCopy);
return (Bitmap)bitmap.Clone();
};
};
}
private Rectangle GetProcessWindowRect(int ProcessId, bool IsClientArea)
{
IntPtr hWnd = Process.GetProcessById(ProcessId).MainWindowHandle;
if (IsClientArea) {
return GetWindowClientRectangle(hWnd);
}
else {
return GetWindowRectangle(hWnd);
}
}
Объявления и помощники Windows APIметоды :
[UIPermission(SecurityAction.Demand, Action = SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
public static Rectangle GetWindowRectangle(IntPtr WindowHandle) {
SafeNativeMethods.GetWindowRect(WindowHandle, out RECT rect);
return rect.ToRectangle();
}
[UIPermission(SecurityAction.Demand, Action = SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
public static Rectangle GetWindowClientRectangle(IntPtr WindowHandle) {
SafeNativeMethods.GetClientRect(WindowHandle, out RECT rect);
SafeNativeMethods.ClientToScreen(WindowHandle, out POINT point);
return rect.ToRectangleOffset(point);
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
public Rectangle ToRectangleOffset(POINT p) => Rectangle.FromLTRB(p.x, p.y, Right + p.x, Bottom + p.y);
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("User32.dll", SetLastError = true)]
internal static extern bool ClientToScreen(IntPtr hWnd, out POINT point);
[DllImport("User32.dll", SetLastError = true)]
internal static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("User32.dll", SetLastError = true)]
internal static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
}