核心鼠標事件處理
雙擊確認截圖
private void ScreenBody_DoubleClick(object sender, EventArgs e)
{
var me = (MouseEventArgs)e;
if (me.Button == MouseButtons.Left && Rect.Contains(me.X, me.Y))
{
// 複製選區到剪貼板
using (Bitmap bmp = new Bitmap(Rect.Width, Rect.Height))
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Rect.X + 1, Rect.Y + 1, 0, 0, Rect.Size);
Clipboard.SetImage(bmp);
}
this.Close();
}
}
鼠標按下:開始選區 / 移動選區 / 右鍵取消
private void ScreenBody_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDowned = true;
if (!RectReady) // 首次按下:記錄起點
{
Rect.X = e.X; Rect.Y = e.Y;
downPoint = new Point(e.X, e.Y);
}
else // 已有選區:記錄移動起點
{
tmpx = e.X; tmpy = e.Y;
}
}
else if (e.Button == MouseButtons.Right)
{
if (!RectReady) { this.Close(); return; } // 無選區直接退出
// 有選區:右鍵重置
MainPainter.DrawImage(baseImage, 0, 0);
RectReady = false;
}
}
鼠標抬起:確認選區完成
private void ScreenBody_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDowned = false;
RectReady = true; // 選區確定
}
}
鼠標移動:拖動選區 / 調整大小 / 移動整個選區
private void ScreenBody_MouseMove(object sender, MouseEventArgs e)
{
if (!RectReady) // 選區未確定:調整大小
{
if (isDowned)
{
using (Image img = DrawScreen((Image)baseImage.Clone(), e.X, e.Y))
MainPainter.DrawImage(img, 0, 0);
}
}
else // 選區已確定:判斷是否在選區內移動
{
if (Rect.Contains(e.X, e.Y) && isDowned)
{
// 計算偏移量
Rect.X += e.X - tmpx;
Rect.Y += e.Y - tmpy;
tmpx = e.X; tmpy = e.Y;
MoveRect((Image)baseImage.Clone(), Rect);
}
}
}
窗體加載初始化
private void ScreenBody_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Maximized;
MainPainter = this.CreateGraphics();
pen = new Pen(Brushes.Blue);
isDowned = false;
baseImage = this.BackgroundImage;
Rect = new Rectangle();
RectReady = false;
}
狀態機總結
| 狀態 | RectReady | isDowned | 行為 |
| 未選區 | false | true | 拖動調整選區大小 |
| 選區完成 | true | false | 靜止顯示選區 |
| 移動選區 | true | true | 整體平移選區 |
| 右鍵取消 | false | - | 恢復背景,重置狀態 |
資源釋放提醒
MainPainter = this.CreateGraphics() 獲取的 Graphics 需在 FormClosed 中 Dispose()。
pen、baseImage 同理。
- 頻繁
Clone() 圖像可能導致內存壓力,建議改用 BufferedGraphics 或僅重繪髒矩形區域。