在多个显示器上捕获屏幕截图
本文关键字:屏幕截图 显示器 | 更新日期: 2023-09-27 18:25:27
作为应用程序的一部分,我希望能够在桌面上抓取所选区域的屏幕截图。不久前,我遇到了如何做到这一点的示例代码(如果我还记得我会引用哪里的话),这个示例运行得很好,但它有多个显示的问题。
它的工作原理是创建一个透明的全屏窗体,然后在其中绘制一条橡皮筋来指定区域。问题是它出现在主显示器上,只允许你在该显示器或其右侧的一个显示器上获取内容。如果你有3个显示器,而你的主显示器是中心,那么就无法获取左侧的内容。
我的问题是如何允许在所有3个显示器上进行捕获。
示例代码:
RubberBand.cs
public partial class RubberBand : Form
{
public Point lastLoc;
public Size lastSize;
bool mouseDown = false;
Point mouseDownPoint = Point.Empty;
Point mousePoint = Point.Empty;
Main mainform;
Pen pen;
Rectangle bounds = new Rectangle();
public RubberBand(Main mainform)
{
this.mainform = mainform;
InitializeComponent();
this.TopMost = true;
this.Opacity = .30;
this.TransparencyKey = System.Drawing.Color.White;
this.Location = new Point(0, 0);
DoubleBuffered = true;
pen = new Pen(System.Drawing.Color.DarkRed, 3);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
int maxX = 0;
int maxY = 0;
foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
{
int x = screen.Bounds.X + screen.Bounds.Width;
if (x > maxX)
maxX = x;
int y = screen.Bounds.Y + screen.Bounds.Height;
if (y > maxY)
maxY = y;
}
bounds.X = 0;
bounds.Y = 0;
bounds.Width = maxX;
bounds.Height = maxY;
this.Size = new Size(bounds.Width, bounds.Height);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
mouseDown = true;
mousePoint = mouseDownPoint = e.Location;
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
mouseDown = false;
// corey
this.lastLoc = new Point(Math.Min(mouseDownPoint.X, mousePoint.X), Math.Min(mouseDownPoint.Y, mousePoint.Y));
this.lastSize = new Size(Math.Abs(mouseDownPoint.X - mousePoint.X), Math.Abs(mouseDownPoint.Y - mousePoint.Y));
this.Close();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
mousePoint = e.Location;
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e);
Region region = new Region(bounds);
if (mouseDown)
{
Rectangle selectionWindow = new Rectangle(
Math.Min(mouseDownPoint.X, mousePoint.X),
Math.Min(mouseDownPoint.Y, mousePoint.Y),
Math.Abs(mouseDownPoint.X - mousePoint.X),
Math.Abs(mouseDownPoint.Y - mousePoint.Y));
// make a hole, where we can see thru this form
region.Xor(selectionWindow);
e.Graphics.FillRegion(Brushes.Black, region);
}
else
{
e.Graphics.FillRegion(Brushes.LightGray, region);
e.Graphics.DrawLine(pen,
mousePoint.X, 0,
mousePoint.X, this.Size.Height);
e.Graphics.DrawLine(pen,
0, mousePoint.Y,
this.Size.Width, mousePoint.Y);
}
}
}
RubberBand.Designer.cs
partial class RubberBand
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// RubberBand
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Cursor = System.Windows.Forms.Cursors.Cross;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "RubberBand";
this.ShowInTaskbar = false;
this.Text = "RubberBand";
this.TransparencyKey = System.Drawing.Color.White;
this.ResumeLayout(false);
}
#endregion
}
这就是调用它的代码:
private void ShowRubberBand()
{
using (RubberBand rbf = new RubberBand(this))
{
rbf.ShowDialog();
Size sLastSize = rbf.lastSize;
if (sLastSize.Width > 0 && sLastSize.Height > 0)
{
Rectangle r = new Rectangle();
r.Location = rbf.lastLoc;
r.Size = sLastSize;
CaptureBitmap(r);
}
}
this.Show();
}
private void CaptureBitmap(Rectangle r)
{
bitmap = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(r.Location, new Point(0, 0), r.Size);
}
PasteImage(bitmap);
}
this.Location = new Point(0, 0);
与主屏幕左上角相关。主(主)屏幕左侧或上方的屏幕具有负位置坐标。在定位窗口和设置窗口大小时,必须将其考虑在内。
在RubberBand构造函数:
int maxX = 0;
int maxY = 0;
int minX = 0;
int minY = 0;
foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
{
int x = screen.Bounds.X + screen.Bounds.Width;
if (x > maxX)
maxX = x;
int y = screen.Bounds.Y + screen.Bounds.Height;
if (y > maxY)
maxY = y;
if(screen.Bound.X < minX) minX = screen.Bound.X;
if(screen.Bound.Y < minY) minY = screen.Bound.Y;
}
bounds.X = minX;
bounds.Y = minY;
bounds.Width = maxX - minX;
bounds.Height = maxY - minY;
this.Location = new Point(bounds.X, bounds.Y);
this.Size = new Size(bounds.Width, bounds.Height);