为什么此 C# 方法无法生成正确的屏幕截图?
Why does this C# method not produce the right screenshot?
我想在 PNG 文件中保存标题以 - Scrivener
结尾的 window 的快照。为此,我写了以下 method (based on this 答案):
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
private void button1_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcesses();
Process scrivenerProcess = null;
foreach (Process curProcess in processes)
{
Console.WriteLine("Name: " + curProcess.ProcessName + ", title: " + curProcess.MainWindowTitle);
if (curProcess.MainWindowTitle.EndsWith("- Scrivener"))
{
scrivenerProcess = curProcess;
break;
}
}
if (scrivenerProcess == null)
{
Console.WriteLine("Scrivener not found");
return;
}
var rect = new RECT();
GetWindowRect(new HandleRef(this, scrivenerProcess.MainWindowHandle), out rect);
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bmp);
graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, new System.Drawing.Size(width, height), CopyPixelOperation.SourceCopy);
bmp.Save("C:\usr\dp\ref\marcomm\2020_04_22_wordCounter\2020-04-24-TestScreenshot.png", ImageFormat.Png);
Console.WriteLine("Heyo!");
}
这段代码有几个问题:
首先,如果我要捕获的应用程序 (Scrivener) 在我调用该代码时不在前台,则生成的屏幕截图为空。
其次,如果 Scrivener window 在前台,我会得到 parent window 的屏幕截图(见下文)。
我需要如何更改我的代码才能使其成为
一个。即使 window 不在前台且
也能正常工作
b。只捕获字数 window(不是它的 parent)?
Here是代码。
这是你的问题:
scrivenerProcess.MainWindowHandle
The main window is the window opened by the process that currently has the focus
在您的屏幕截图中,您所关注的 window 没有 具有焦点(它具有白色背景和灰色文本,表明它处于非活动状态)。
不幸的是,要枚举进程的其他 windows,您需要使用 P/Invoke,因为它们不会通过 Process
class 公开。 Use EnumWindows
or EnumChildWindows
.
我想在 PNG 文件中保存标题以 - Scrivener
结尾的 window 的快照。为此,我写了以下 method (based on this 答案):
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
private void button1_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcesses();
Process scrivenerProcess = null;
foreach (Process curProcess in processes)
{
Console.WriteLine("Name: " + curProcess.ProcessName + ", title: " + curProcess.MainWindowTitle);
if (curProcess.MainWindowTitle.EndsWith("- Scrivener"))
{
scrivenerProcess = curProcess;
break;
}
}
if (scrivenerProcess == null)
{
Console.WriteLine("Scrivener not found");
return;
}
var rect = new RECT();
GetWindowRect(new HandleRef(this, scrivenerProcess.MainWindowHandle), out rect);
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bmp);
graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, new System.Drawing.Size(width, height), CopyPixelOperation.SourceCopy);
bmp.Save("C:\usr\dp\ref\marcomm\2020_04_22_wordCounter\2020-04-24-TestScreenshot.png", ImageFormat.Png);
Console.WriteLine("Heyo!");
}
这段代码有几个问题:
首先,如果我要捕获的应用程序 (Scrivener) 在我调用该代码时不在前台,则生成的屏幕截图为空。
其次,如果 Scrivener window 在前台,我会得到 parent window 的屏幕截图(见下文)。
我需要如何更改我的代码才能使其成为
一个。即使 window 不在前台且
也能正常工作b。只捕获字数 window(不是它的 parent)?
Here是代码。
这是你的问题:
scrivenerProcess.MainWindowHandle
The main window is the window opened by the process that currently has the focus
在您的屏幕截图中,您所关注的 window 没有 具有焦点(它具有白色背景和灰色文本,表明它处于非活动状态)。
不幸的是,要枚举进程的其他 windows,您需要使用 P/Invoke,因为它们不会通过 Process
class 公开。 Use EnumWindows
or EnumChildWindows
.