-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathSelectionForm.cs
More file actions
141 lines (120 loc) · 4.44 KB
/
SelectionForm.cs
File metadata and controls
141 lines (120 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
namespace ScreenOCRTranslator
{
public partial class SelectionForm : Form
{
private Point startPoint;
private Rectangle selectedRect;
private Rectangle selectedRectScreen; // 螢幕絕對座標(回傳用)
private Bitmap backgroundScreenshot;
private bool isDragging = false;
public event Action<Bitmap, Rectangle> OnSelectionCompleted;
// ✅ 改:回傳螢幕絕對座標
public Rectangle SelectedRectangle => selectedRectScreen;
public SelectionForm()
{
this.DoubleBuffered = true;
this.FormBorderStyle = FormBorderStyle.None;
this.Opacity = 1;
this.BackColor = Color.Gray;
this.TopMost = true;
this.Cursor = Cursors.Cross;
this.ShowInTaskbar = false;
var screen = Screen.FromPoint(Cursor.Position);
this.StartPosition = FormStartPosition.Manual;
this.WindowState = FormWindowState.Normal;
this.Bounds = screen.Bounds;
backgroundScreenshot = new Bitmap(this.Bounds.Width, this.Bounds.Height);
using (Graphics g = Graphics.FromImage(backgroundScreenshot))
{
g.CopyFromScreen(this.Bounds.Location, Point.Empty, this.Bounds.Size);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = true;
startPoint = e.Location;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (isDragging)
{
selectedRect = new Rectangle(
Math.Min(startPoint.X, e.X),
Math.Min(startPoint.Y, e.Y),
Math.Abs(startPoint.X - e.X),
Math.Abs(startPoint.Y - e.Y)
);
this.Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (!isDragging) return;
isDragging = false;
if (selectedRect.Width < 5 || selectedRect.Height < 5)
{
this.Close();
return;
}
// ✅ 這個才是螢幕絕對座標(可為負值、可超過主螢幕寬度)
var absoluteRect = new Rectangle(
this.Bounds.Left + selectedRect.Left,
this.Bounds.Top + selectedRect.Top,
selectedRect.Width,
selectedRect.Height
);
selectedRectScreen = absoluteRect;
Bitmap capture = new Bitmap(absoluteRect.Width, absoluteRect.Height);
using (Graphics g = Graphics.FromImage(capture))
{
g.CopyFromScreen(absoluteRect.Location, Point.Empty, absoluteRect.Size);
}
OnSelectionCompleted?.Invoke(capture, absoluteRect);
this.DialogResult = DialogResult.OK;
this.Close();
}
protected override void OnPaint(PaintEventArgs e)
{
if (backgroundScreenshot != null)
{
e.Graphics.DrawImage(backgroundScreenshot, Point.Empty);
}
using (var dimBrush = new SolidBrush(Color.FromArgb(120, Color.Gray)))
{
e.Graphics.FillRectangle(dimBrush, this.ClientRectangle);
}
if (selectedRect != Rectangle.Empty)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
var outerRect = Rectangle.Inflate(selectedRect, 3, 3);
using (Pen outerPen = new Pen(Color.FromArgb(255, Color.LightBlue), 3f))
{
e.Graphics.DrawRectangle(outerPen, outerRect);
}
using (Pen pen = new Pen(Color.FromArgb(255, Color.Red), 2.5f))
{
e.Graphics.DrawRectangle(pen, selectedRect);
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
backgroundScreenshot?.Dispose();
}
base.Dispose(disposing);
}
}
}