Я делаю приложение на C#, которое предназначено для имитации внешнего вида и поведения приложения Windows Snipping Tool. Все в порядке, за исключением того факта, что двойная буферизация (чтобы остановить мерцание экрана) появляется медленно и лагги. Это немного отстает, но этого достаточно, чтобы быть заметным, особенно при сравнении производительности между моей программой и Snipping Tool. Что еще я могу сделать, чтобы улучшить производительность и создать впечатление, что нет отставания, например, в Snipping Tool?C# Двойная буферизация вызывает отставание от краски
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, но он все еще работает намного быстрее.
Это, несомненно, увеличивает производительность в десятки раз. Единственное, что я замечаю сейчас, это то, что выбор начинает снова отставать, если он становится слишком большим. Я использую двойной монитор, и эффекты смутно начинают повторяться (не так уж плохо), когда я перетягиваюсь с обоих экранов. Это не так заметно, как раньше, но это определенно намного лучше. Благодаря! – Dragonphase
На самом деле, поцарапайте это, я просто сравнил его с Windows Snipping tool, это практически то же самое! Еще раз спасибо! – Dragonphase
См. Ревизию, в которой регион расположен с помощью функции «Использование». –