2013-12-25 1 views
1

Я разрабатываю приложение для обрезки с помощью C#. Когда нажата кнопка захвата в Form1, я скрываю Form1 и снимаю скриншот фонового экрана, но проблема заключается в скриншоте, которое показывает окно Form1, хотя я выполняю это. Hide(); сначала, а затем снимать снимок экрана. Пожалуйста, помогите мне, как сделать Form1 не отображаться на скриншоте.Form1 захватывается даже после его утаивания

Вот мой код:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Diagnostics; 

namespace WindowsFormsApplication5 
{ 
    public partial class Form1 : Form 
    { 
     public static Image fullDesktop; 
     public static Image partIamge; 
     public static Form backgroundForm; 
     public static PictureBox picbox1; 

     public static Point mouseDownAt; 
     public static Point mouseIsAt; 
     public static bool isMouseDown = false; 

     public static Color backgroundColor = Color.DarkGray; 
     public static int backgroundAlpha = 150; 
     public static Color outlineColor = Color.Red; 
     public static int outlineWidth = 1; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public void Initialize() 
     { 
      backgroundForm = new Form(); 
      backgroundForm.FormBorderStyle = FormBorderStyle.None; 
      backgroundForm.WindowState = FormWindowState.Maximized; 
      backgroundForm.Cursor = Cursors.Cross; 

      picbox1 = new PictureBox(); 
      picbox1.Size = Screen.FromControl(backgroundForm).Bounds.Size; 
      picbox1.Location = new Point(0, 0); 
      picbox1.Image = fullDesktop; 
      picbox1.BorderStyle = BorderStyle.None; 
      picbox1.Paint += new PaintEventHandler(OnPaint); 
      picbox1.MouseDown += new MouseEventHandler(OnMouseDown); 
      picbox1.MouseMove += new MouseEventHandler(OnMouseMove); 
      picbox1.MouseUp += new MouseEventHandler(OnMouseUp); 
      backgroundForm.KeyDown += new KeyEventHandler(OnKeyDown); 
      backgroundForm.KeyPreview = true; 
      backgroundForm.Controls.Add(picbox1); 
     } 

     public void OnKeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.KeyCode == Keys.Escape) 
       backgroundForm.Close(); 
     } 
     public void OnPaint(object sender, PaintEventArgs e) 
     { 
      SolidBrush opaqueWhiteBrush = new SolidBrush(Color.FromArgb(backgroundAlpha, backgroundColor.R, backgroundColor.G, backgroundColor.B)); 
      e.Graphics.FillRectangle(opaqueWhiteBrush, 0, 0, picbox1.Width, picbox1.Height); 

      if (isMouseDown) 
      { 
       Rectangle pos = getMouseMoveRect; 
       e.Graphics.DrawRectangle(new Pen(outlineColor, outlineWidth), new Rectangle(pos.X - outlineWidth, pos.Y - outlineWidth, pos.Width + outlineWidth, pos.Height + outlineWidth)); 
       e.Graphics.DrawImage(partIamge, pos.Location); 

       //string displayText = "W: " + pos.Width + " H: " + pos.Height; 
       //Font font = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Pixel); 
       //e.Graphics.DrawString(displayText, font, Brushes.White, pos.X, pos.Y - font.Size - 6, StringFormat.GenericDefault); 
      } 
     } 

     public void OnMouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Right && !isMouseDown) 
      { 
       //Application.Exit(); 
       //backgroundForm.Close(); 
      } 
      else if (e.Button == MouseButtons.Left) 
      { 
       mouseDownAt = e.Location; 
       Cursor.Position = new Point(e.Location.X + 1, e.Location.Y + 1); 
       mouseIsAt = new Point(e.Location.X + 1, e.Location.Y + 1); 
       partIamge = ((Bitmap)fullDesktop).Clone(getMouseMoveRect, fullDesktop.PixelFormat); 
       isMouseDown = true; 
       picbox1.Refresh(); 
      } 
     } 

     public void OnMouseMove(object sender, MouseEventArgs e) 
     { 
      if (isMouseDown) 
      { 
       mouseIsAt = e.Location; 
       Rectangle rect = getMouseMoveRect; 
       if (rect.Width != 0 && rect.Height != 0) 
       { 
        partIamge = ((Bitmap)fullDesktop).Clone(rect, fullDesktop.PixelFormat); 
        picbox1.Refresh(); 
       } 
      } 
     } 

     public void OnMouseUp(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
      { 
       bool hasMoved = false; 

       if (isMouseDown) 
       { 
        hasMoved = true; 
        isMouseDown = false; 
       } 

       SaveFileDialog sfd = new SaveFileDialog(); 
       sfd.Filter = "PNG image (*.png)|*.png"; 
       if (sfd.ShowDialog() == DialogResult.OK) 
       { 
        partIamge.Save(sfd.FileName, ImageFormat.Png); 
        Clipboard.SetImage(partIamge); 
       } 
       else 
       { 
        hasMoved = false; 
        picbox1.Refresh(); 
       } 

       if (hasMoved) 
       { 
        backgroundForm.Close(); 
       } 
      } 
     } 

     public Rectangle getMouseMoveRect 
     { 
      get 
      { 
       int x = 0; 
       int y = 0; 
       int width = 0; 
       int height = 0; 

       if (mouseIsAt.X > mouseDownAt.X) 
       { 
        x = mouseDownAt.X; 
        width = mouseIsAt.X - mouseDownAt.X; 
       } 
       else 
       { 
        x = mouseIsAt.X; 
        width = mouseDownAt.X - mouseIsAt.X; 
       } 

       if (mouseIsAt.Y > mouseDownAt.Y) 
       { 
        y = mouseDownAt.Y; 
        height = mouseIsAt.Y - mouseDownAt.Y; 
       } 
       else 
       { 
        y = mouseIsAt.Y; 
        height = mouseDownAt.Y - mouseIsAt.Y; 
       } 

       return new Rectangle(x, y, width, height); 
      } 
     } 

     public Image CaptureScreen 
     { 
      get 
      { 
       Bitmap image = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
       using (Graphics g = Graphics.FromImage(image)) 
       { 
        g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, 
          Screen.PrimaryScreen.Bounds.Y, 
          0, 0, 
          image.Size, 
          CopyPixelOperation.SourceCopy); 
       } 

       return image; 
      } 
     } 

     private void cmdCapture_Click(object sender, EventArgs e) 
     { 

      this.Hide(); 

      fullDesktop = CaptureScreen; 
      Initialize(); 

      backgroundForm.ShowDialog(); 
      this.Show(); 
     } 

     private void cmdExit_Click(object sender, EventArgs e) 
     { 
      Application.Exit(); 
     } 

     private void Form1_Closed(object sender, EventArgs e) 
     { 
      Application.Exit(); 
     } 

     private void cmdFullCapture_Click(object sender, EventArgs e) 
     { 
      this.WindowState = FormWindowState.Minimized; 
      this.Hide(); 

      while (IsOnScreen(this)) ; 
      fullDesktop = CaptureScreen; 
      SaveFileDialog sfd = new SaveFileDialog(); 
      sfd.Filter = "PNG image (*.png)|*.png"; 
      if (sfd.ShowDialog() == DialogResult.OK) 
      { 
       fullDesktop.Save(sfd.FileName, ImageFormat.Png); 
       Clipboard.SetImage(partIamge); 
      } 
      this.Show(); 
      this.WindowState = FormWindowState.Normal; 
     } 

    } 
} 

Заранее спасибо.

+0

Угадай, но я бы сказал, что захват стреляет до того, как форма обрабатывает запрос на скрытие. Обработчик событий, который срабатывает после скрытия формы, должен делать трюк. –

+0

Не могли бы вы рассказать мне, как это сделать. – user3134467

+0

Событие VisibleChanged формы, которую вы хотите скрыть, должно делать. Вы можете просто переместить в него свой код захвата, вызвать у него код захвата или добавить Oncaptureevent в свой код и запустить его из видимого измененного события. Не уверен, вызвано ли событие при изменении видимого свойства свойства, поэтому вам может потребоваться задержка или вызов от участников. –

ответ

2

Это проблема в старых версиях Windows, вы захватываете пиксели в буфере кадров видеоадаптера. Когда вы скрываете свое окно, другим окнам нужно сначала перерисовать их, чтобы обновить пиксели в буфере, которые когда-то были нарисованы вашим окном. Это требует времени, непредсказуемого количества времени. Вы не ждете вообще, так что вы все равно получаете старые пиксели своего окна.

Для этого есть простой способ обхода, вы также можете использовать свойство Opacity формы, чтобы скрыть окно. Непрозрачность реализована в наложением внутри самого видеоадаптера. Установите непрозрачность 99 в дизайнере. На самом деле, ваше окно больше не будет захвачено. На самом деле это ошибка, она исправлена ​​в Windows 8. Поэтому не оставляйте это так, установите Opacity в 0 перед тем, как сделать снимок экрана, а затем снова на 0.99 (а не на опечатку).

+0

Спасибо, Ханс Пассант ... Он работает ..... Большое вам спасибо. – user3134467

0

Может быть, вы можете попробовать изменения WindowState вашей формы программно:

Вместо:

this.Hide(); 

Try:

this.WindowState = FormWindowState.Minimized; 

И после того, как взять скриншот:

this.WindowState = FormWindowState.Normal; 
+0

Спасибо за ответ Selman22. Но я все еще сталкиваюсь с той же проблемой. Form1 все еще появляется на скриншоте даже после минимизации окна Form1. – user3134467

Смежные вопросы