我一直在用 C# 制作一个应用程序,旨在模仿 Windows 的 Snipping Tool 应用程序的外观和行为。一切都很好,除了双重缓冲(停止屏幕闪烁)显得缓慢而滞后。延迟并不多,但足以引起注意,尤其是在比较我的程序和 Snipping Tool 之间的性能时。我还能做些什么来提高性能并让它看起来没有延迟,就像在截图工具中一样?
public Image Image { get; set; }
private Rectangle selection;
private Point startPoint;
public static Image Snip()
{
using (var bmp = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
{
using (var graphics = Graphics.FromImage(bmp)) graphics.CopyFromScreen(SystemInformation.VirtualScreen.Left, SystemInformation.VirtualScreen.Top, 0, 0, bmp.Size);
using (var snipper = new CaptureScreen(bmp, new Point(SystemInformation.VirtualScreen.Left, SystemInformation.VirtualScreen.Top)))
{
if (snipper.ShowDialog() == DialogResult.OK) return snipper.Image;
}
return null;
}
}
public CaptureScreen(Image screenShot, Point startPos)
{
InitializeComponent();
Cursor = Cursors.Cross;
BackgroundImage = screenShot;
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.None;
StartPosition = FormStartPosition.Manual;
Size = screenShot.Size;
Location = startPos;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
startPoint = e.Location;
selection = new Rectangle(e.Location, new Size(0, 0));
Invalidate();
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
var x1 = Math.Min(e.X, startPoint.X);
var y1 = Math.Min(e.Y, startPoint.Y);
var x2 = Math.Max(e.X, startPoint.X);
var y2 = Math.Max(e.Y, startPoint.Y);
selection = new Rectangle(x1, y1, x2 - x1, y2 - y1);
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (selection.Width <= 0 || selection.Height <= 0) return;
Image = new Bitmap(selection.Width, selection.Height);
using (var gr = Graphics.FromImage(Image))
{
gr.DrawImage(BackgroundImage, new Rectangle(0, 0, Image.Width, Image.Height),
selection, GraphicsUnit.Pixel);
}
DialogResult = DialogResult.OK;
}
protected override void OnPaint(PaintEventArgs e)
{
using (var br = new SolidBrush(Color.FromArgb(127, Color.White)))
{
var x1 = selection.X;
var x2 = selection.X + selection.Width;
var y1 = selection.Y;
var y2 = selection.Y + selection.Height;
e.Graphics.FillRectangle(br, new Rectangle(0, 0, x1, Height));
e.Graphics.FillRectangle(br, new Rectangle(x2, 0, Width - x2, Height));
e.Graphics.FillRectangle(br, new Rectangle(x1, 0, x2 - x1, y1));
e.Graphics.FillRectangle(br, new Rectangle(x1, y2, x2 - x1, Height - y2));
}
using (var pen = new Pen(Color.Red, 1))
{
e.Graphics.DrawRectangle(pen, selection);
}
}
我认为它以这种方式滞后的原因是因为应用程序创建了一个屏幕截图并调整了捕获窗口的大小以匹配所有屏幕的尺寸。我有一种感觉,这也是 Snipping Tool 所做的,但它仍然执行得更快。