画面の範囲選択をさせたいときに役立つかも...?
環境
.NetFramework
WinForm
完成品
コード
public partial class CaptureForm : Form
{
/// <summary>
/// 選択範囲
/// </summary>
public Rectangle SelectRegion { get; private set; }
/// <summary>
/// 選択の開始位置
/// </summary>
private Point startPoint;
/// <summary>
/// 選択中の現在位置
/// </summary>
private Point currentPoint;
/// <summary>
/// 選択前のカーソル状態
/// </summary>
private Cursor cursorRestore;
public CaptureForm()
{
InitializeComponent();
BackColor = Color.Black;
Opacity = 0.7;
FormBorderStyle = FormBorderStyle.None;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var screenRectangle = GetSceenRectangle();
Location = screenRectangle.Location;
Size = screenRectangle.Size;
}
private void CampusForm_MouseDown(object sender, MouseEventArgs e)
{
startPoint=e.Location;
cursorRestore = Cursor;
Cursor = Cursors.Cross;
}
private void CampusForm_MouseMove(object sender, MouseEventArgs e)
{
currentPoint = e.Location;
Invalidate();
}
private void CampusForm_MouseUp(object sender, MouseEventArgs e)
{
Invalidate();
Cursor = cursorRestore;
DialogResult = DialogResult.OK;
Close();
}
private void CampusForm_Paint(object sender, PaintEventArgs e)
{
if (MouseButtons != MouseButtons.Left) return;
SelectRegion = GetSelectRegion();
}
/// <summary>
/// 選択範囲を取得.
/// </summary>
private Rectangle GetSelectRegion()
{
var region = new Rectangle
{
X = Math.Min(startPoint.X, currentPoint.X),
Y = Math.Min(startPoint.Y, currentPoint.Y),
Width = Math.Abs(currentPoint.X - startPoint.X),
Height = Math.Abs(currentPoint.Y - startPoint.Y)
};
var regionNew = new Region(ClientRectangle);
using (var path = new System.Drawing.Drawing2D.GraphicsPath())
{
path.AddRectangle(region);
regionNew.Exclude(region);
}
var regionOld = Region;
Region = regionNew;
regionOld?.Dispose();
return region;
}
/// <summary>
/// すべてのスクリーンを合わせた四角形のサイズと位置を表す<see cref="Rectangle"/>を取得.
/// </summary>
private Rectangle GetSceenRectangle()
{
var screens = Screen.AllScreens;
// 一番小さいx (左上のx座標)
var minX = screens.Min(screen => screen.Bounds.X);
// 一番小さいy (左上のy座標)
var minY = screens.Min(screen => screen.Bounds.Y);
// 一番大きいx (右下のx座標)
var maxX = screens.Max(screen => screen.Bounds.X + screen.Bounds.Width);
// 一番大きいy (右下のy座標)
var maxY = screens.Max(screen => screen.Bounds.Y + screen.Bounds.Height);
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}
}
MouseUpのタイミングでクリップボードにコピーすると、[Win]+[Shift]+[S]みたいなコピーも可能に。
/// <summary>
/// 選択範囲をクリップボードにコピーします。
/// </summary>
private void CopyToClipboard()
{
var bmp = new Bitmap(SelectRegion.Width, SelectRegion.Height);
using (var graphics = Graphics.FromImage(bmp))
{
var screenRectangle = GetSceenRectangle();
graphics.CopyFromScreen(SelectRegion.X + screenRectangle.X
, SelectRegion.Y + screenRectangle.Y, 0, 0, SelectRegion.Size);
Clipboard.SetImage(bmp);
};
}