first commit
This commit is contained in:
commit
761b95080f
404 files changed
+312608
No files matched your search
@@ -0,0 +1,133 @@
|
||||
using anjianjingling.Native;
|
||||
|
||||
namespace anjianjingling.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// 全屏框选截图:鼠标拖拽框选区域,松开后截图保存到 images 目录。
|
||||
/// ESC 取消。
|
||||
/// </summary>
|
||||
public sealed class OverlayForm : Form
|
||||
{
|
||||
private Point _start, _end;
|
||||
private bool _dragging;
|
||||
private Rectangle _selected;
|
||||
public string? SavedPath { get; private set; }
|
||||
public event Action<string>? OnSaved;
|
||||
|
||||
/// <summary>是否把框选结果保存为图片(录屏取区域时设为 false)。</summary>
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
[System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
|
||||
public bool SaveToFile { get; set; } = true;
|
||||
|
||||
/// <summary>最近一次框选的屏幕矩形。</summary>
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
[System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
|
||||
public Rectangle SelectedRect { get; private set; }
|
||||
|
||||
public OverlayForm()
|
||||
{
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
Bounds = SystemInformation.VirtualScreen;
|
||||
TopMost = true;
|
||||
ShowInTaskbar = false;
|
||||
DoubleBuffered = true;
|
||||
KeyPreview = true;
|
||||
BackColor = Color.Black;
|
||||
Opacity = 0.25;
|
||||
Cursor = Cursors.Cross;
|
||||
|
||||
MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
_dragging = true;
|
||||
_start = _end = PointToScreen(e.Location);
|
||||
}
|
||||
};
|
||||
MouseMove += (s, e) =>
|
||||
{
|
||||
if (_dragging)
|
||||
{
|
||||
_end = PointToScreen(e.Location);
|
||||
var r = RectangleFromPoints(_start, _end);
|
||||
_selected = r;
|
||||
Invalidate();
|
||||
}
|
||||
};
|
||||
MouseUp += (s, e) =>
|
||||
{
|
||||
if (_dragging && e.Button == MouseButtons.Left)
|
||||
{
|
||||
_dragging = false;
|
||||
var r = RectangleFromPoints(_start, _end);
|
||||
if (r.Width > 4 && r.Height > 4)
|
||||
{
|
||||
SelectedRect = r;
|
||||
if (SaveToFile)
|
||||
{
|
||||
string dir = Path.Combine(AppContext.BaseDirectory, "images");
|
||||
Directory.CreateDirectory(dir);
|
||||
string file = Path.Combine(dir,
|
||||
$"clip_{DateTime.Now:yyyyMMdd_HHmmss}.png");
|
||||
using (var bmp = new Bitmap(r.Width, r.Height))
|
||||
using (var g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.CopyFromScreen(r.Left, r.Top, 0, 0, r.Size);
|
||||
bmp.Save(file, System.Drawing.Imaging.ImageFormat.Png);
|
||||
}
|
||||
SavedPath = file;
|
||||
OnSaved?.Invoke(file);
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
};
|
||||
KeyDown += (s, e) =>
|
||||
{
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
if (_selected.Width > 0)
|
||||
{
|
||||
// 用屏幕坐标转客户区绘制
|
||||
var r = ScreenRectToClient(_selected);
|
||||
using (var pen = new Pen(Color.Lime, 1))
|
||||
{
|
||||
e.Graphics.DrawRectangle(pen, r);
|
||||
string info = $"{_selected.Width} x {_selected.Height} ({_selected.Left},{_selected.Top})";
|
||||
using var font = new Font("Consolas", 9F);
|
||||
var sz = e.Graphics.MeasureString(info, font);
|
||||
float ty = r.Top - sz.Height - 2;
|
||||
if (ty < 0) ty = r.Bottom + 2;
|
||||
using var bg = new SolidBrush(Color.Lime);
|
||||
e.Graphics.FillRectangle(bg, r.Left, ty, sz.Width, sz.Height);
|
||||
e.Graphics.DrawString(info, font, Brushes.Black, r.Left, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Rectangle RectangleFromPoints(Point a, Point b)
|
||||
=> Rectangle.FromLTRB(
|
||||
Math.Min(a.X, b.X), Math.Min(a.Y, b.Y),
|
||||
Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
|
||||
|
||||
private Rectangle ScreenRectToClient(Rectangle screen)
|
||||
{
|
||||
var a = PointToClient(new Point(screen.Left, screen.Top));
|
||||
var b = PointToClient(new Point(screen.Right, screen.Bottom));
|
||||
return new Rectangle(a.X, a.Y, b.X - a.X, b.Y - a.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user