2013-07-28 2 views
1

В качестве части моего приложения я хотел бы получить снимок экрана выбранной области на моем рабочем столе. Я натолкнулся на пример кода о том, как это сделать некоторое время назад (если бы я мог вспомнить, где бы я цитировал), и пример хорошо работает, однако у него есть проблема с несколькими дисплеями.Захват скриншота на нескольких дисплеях

Он работает, создавая прозрачную полноэкранную форму, а затем вы рисуете в ней резиновую ленту, чтобы обозначить область. Проблема в том, что она появляется на основном дисплее и позволяет вам захватывать контент на этом дисплее или один справа от него. Если у вас есть 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); 
    } 

ответ

2

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); 
Смежные вопросы