我正在使用c#开发一个剪切工具应用程序。单击Form1中的捕获按钮时,我隐藏了Form1并截取了背景屏幕的截图,但问题出现在Form1窗口显示的屏幕截图中,即使我正在执行this.Hide();首先声明然后截取屏幕截图。请帮我看看如何使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 :(得分:2)
这是旧版Windows上的一个问题,您可以捕获视频适配器帧缓冲区中的像素。当您隐藏窗口时,其他窗口需要首先重新绘制自己,以更新窗口绘制的缓冲区中的像素。这需要时间,这是一段不可预测的时间。你不要等待,所以你仍然可以获得窗口的旧像素。
有一个简单的解决方法,您还可以使用表单的Opacity属性来隐藏窗口。不透明度由视频适配器本身内的分层实现。在设计器中将不透明度设置为99。这实际上已经足够了,您的窗口将不再被捕获。这实际上是一个错误,它在Windows 8中得到修复。所以不要这样做,在屏幕截图之前将代码中的不透明度设置为0,然后再回到0.99(不是拼写错误)。
答案 1 :(得分:0)
也许您可以以编程方式尝试更改表单的WindowState
:
而不是:
this.Hide();
尝试:
this.WindowState = FormWindowState.Minimized;
截取屏幕截图后:
this.WindowState = FormWindowState.Normal;