
Catch)**問題**:直接在視窗繪製矩形,滑鼠移動會留下大量殘影矩形。
**方案二(採用)**:雙重緩衝離屏繪製
originBmpClone() 原始圖 → 在副本上畫矩形 → 整體繪製到視窗
public partial class Catch : Form
{
private Point DownPoint = Point.Empty;
private bool CatchFinished = false;
private bool CatchStart = false;
private Bitmap originBmp;
private Rectangle CatchRect;
private void Catch_Load(object sender, EventArgs e)
{
// 雙緩衝設定
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);
this.UpdateStyles();
originBmp = new Bitmap(this.BackgroundImage);
}
private void Catch_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && !CatchStart)
{
CatchStart = true;
DownPoint = new Point(e.X, e.Y);
}
}
private void Catch_MouseMove(object sender, MouseEventArgs e)
{
if (CatchStart)
{
Bitmap destBmp = (Bitmap)originBmp.Clone();
Point newPoint = new Point(DownPoint.X, DownPoint.Y);
Graphics g = Graphics.FromImage(destBmp);
Pen p = new Pen(Color.Blue, 1);
int width = Math.Abs(e.X - DownPoint.X);
int height = Math.Abs(e.Y - DownPoint.Y);
if (e.X < DownPoint.X) newPoint.X = e.X;
if (e.Y < DownPoint.Y) newPoint.Y = e.Y;
CatchRect = new Rectangle(newPoint, new Size(width, height));
g.DrawRectangle(p, CatchRect);
g.Dispose(); p.Dispose();
// 繪製到視窗
Graphics g1 = this.CreateGraphics();
g1.DrawImage(destBmp, new Point(0, 0));
g1.Dispose();
destBmp.Dispose();
}
}
private void Catch_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && CatchStart)
{
CatchStart = false;
CatchFinished = true;
}
}
private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && CatchFinished &&
CatchRect.Contains(new Point(e.X, e.Y)))
{
Bitmap caughtBmp = new Bitmap(CatchRect.Width, CatchRect.Height);
Graphics g = Graphics.FromImage(caughtBmp);
g.DrawImage(originBmp,
new Rectangle(0, 0, CatchRect.Width, CatchRect.Height),
CatchRect, GraphicsUnit.Pixel);
Clipboard.SetImage(caughtBmp);
g.Dispose(); caughtBmp.Dispose();
this.BackgroundImage = originBmp;
CatchFinished = false;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
private void Catch_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}
private void bCatch_Click(object sender, EventArgs e)
{
if (bCatch_HideCurrent.Checked)
{
this.Hide();
Thread.Sleep(50);
Catch catchForm = new Catch();
Bitmap screenBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width,
Screen.AllScreens[0].Bounds.Height);
Graphics g = Graphics.FromImage(screenBmp);
g.CopyFromScreen(Point.Empty, Point.Empty, screenBmp.Size);
catchForm.BackgroundImage = screenBmp;
if (catchForm.ShowDialog() == DialogResult.OK)
{
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Bitmap))
{
richtextbox1.Paste(DataFormats.GetFormat(DataFormats.Bitmap));
Clipboard.Clear();
}
this.Show();
}
}
}
CopyFromScreen:高效全螢幕截圖Bitmap.Clone():快速複製原始圖避免修改Graphics.DrawImage:離屏繪製後整體呈現ControlStyles.OptimizedDoubleBuffer:系統級雙緩衝Clipboard.SetImage/GetDataObject:跨視窗圖片傳遞