1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Win]+[Shift]+[S]のような範囲選択をC#で

Posted at

画面の範囲選択をさせたいときに役立つかも...?

環境

.NetFramework
WinForm

完成品

Animation.gif

コード

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);
    };
}
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?