Skip to content

Instantly share code, notes, and snippets.

@smourier
Created May 25, 2018 14:09
Show Gist options
  • Save smourier/8d0e73a7bff39698bbd681bdd51efae5 to your computer and use it in GitHub Desktop.
Save smourier/8d0e73a7bff39698bbd681bdd51efae5 to your computer and use it in GitHub Desktop.
/*
* Credit for this portion of Imgur Snipping Tool goes to Hans Passant from stackoverflow.com
* http://stackoverflow.com/questions/3123776/net-equivalent-of-snipping-tool
*
* Modified to work with multiple monitors.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Free_Snipping_Tool_project;
namespace Free_Snipping_Tool_project
{
public partial class SnippingTool : Form
{
public enum ScreenshotType
{
FULL, ACTIVE, DEFINED
}
private int oldX;
private int oldY;
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
Rectangle topLeft = new Rectangle();
Rectangle topMiddle = new Rectangle();
Rectangle topRight = new Rectangle();
Rectangle bottomLeft = new Rectangle();
Rectangle bottomMiddle = new Rectangle();
Rectangle bottomRight = new Rectangle();
Rectangle leftMiddle = new Rectangle();
Rectangle rightMiddle = new Rectangle();
bool topLeftSelected = false;
bool topMiddleSelected = false;
bool topRightSelected = false;
bool bottomLeftSelected = false;
bool bottomMiddleSelected = false;
bool bottomRightSelected = false;
bool leftMiddleSelected = false;
bool rightMiddleSelected = false;
bool rectangleSelected = false;
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern int GetForegroundWindow();
SnipSizeControl lbl = new SnipSizeControl();
public static Image Snip(ScreenshotType type)
{
switch (type)
{
case ScreenshotType.FULL:
return CreateScreenshot(0, 0, SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height);
case ScreenshotType.DEFINED:
SnippingTool snipper = new SnippingTool(CreateScreenshot(0, 0, SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height), new Point(SystemInformation.VirtualScreen.Left, SystemInformation.VirtualScreen.Top));
if (snipper.ShowDialog() == DialogResult.OK)
{
return snipper.Image;
}
break;
case ScreenshotType.ACTIVE:
RECT windowRectangle;
GetWindowRect((System.IntPtr)GetForegroundWindow(), out windowRectangle);
return CreateScreenshot(windowRectangle.Left, windowRectangle.Top, windowRectangle.Right - windowRectangle.Left, windowRectangle.Bottom - windowRectangle.Top);
}
return null;
}
private static Bitmap CreateScreenshot(int left, int top, int width, int height)
{
Bitmap bmp = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(left, top, 0, 0, new Size(width, height));
g.Dispose();
return bmp;
}
public SnippingTool(Image screenShot, Point startPos)
{
InitializeComponent();
lbl.Text = "0x0";
lbl.Visible = true;
lbl.BackColor = Color.Black;
lbl.ForeColor = Color.White;
lbl.Visible = false;
this.Controls.Add(lbl);
this.BackgroundImage = screenShot;
Size s = screenShot.Size;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.Manual;
this.Size = s;
this.Location = startPos;
this.DoubleBuffered = true;
}
public Image Image { get; set; }
private Rectangle rcSelect = new Rectangle();
private Rectangle oldRcSelect = new Rectangle();
private Point pntStart;
bool handleSelected = false;
protected override void OnMouseDown(MouseEventArgs e)
{
if ((e.X > topLeft.X) && (e.X < topLeft.X + topLeft.Width) && (e.Y > topLeft.Y) && (e.Y < topLeft.Y + topLeft.Height))
{
this.Cursor = Cursors.SizeNWSE;
topLeftSelected = true;
handleSelected = true;
}
else if ((e.X > topMiddle.X) && (e.X < topMiddle.X + topMiddle.Width) && (e.Y > topMiddle.Y) && (e.Y < topMiddle.Y + topMiddle.Height))
{
this.Cursor = Cursors.SizeNS;
topMiddleSelected = true;
handleSelected = true;
}
else if ((e.X > topRight.X) && (e.X < topRight.X + topRight.Width) && (e.Y > topRight.Y) && (e.Y < topRight.Y + topRight.Height))
{
this.Cursor = Cursors.SizeNESW;
topRightSelected = true;
handleSelected = true;
}
else if ((e.X > bottomLeft.X) && (e.X < bottomLeft.X + bottomLeft.Width) && (e.Y > bottomLeft.Y) && (e.Y < bottomLeft.Y + bottomLeft.Height))
{
this.Cursor = Cursors.SizeNESW;
bottomLeftSelected = true;
handleSelected = true;
}
else if ((e.X > bottomMiddle.X) && (e.X < bottomMiddle.X + bottomMiddle.Width) && (e.Y > bottomMiddle.Y) && (e.Y < bottomMiddle.Y + bottomMiddle.Height))
{
this.Cursor = Cursors.SizeNS;
bottomMiddleSelected = true;
handleSelected = true;
}
else if ((e.X > bottomRight.X) && (e.X < bottomRight.X + bottomRight.Width) && (e.Y > bottomRight.Y) && (e.Y < bottomRight.Y + bottomRight.Height))
{
this.Cursor = Cursors.SizeNWSE;
bottomRightSelected = true;
handleSelected = true;
}
else if ((e.X > leftMiddle.X) && (e.X < leftMiddle.X + leftMiddle.Width) && (e.Y > leftMiddle.Y) && (e.Y < leftMiddle.Y + leftMiddle.Height))
{
this.Cursor = Cursors.SizeWE;
leftMiddleSelected = true;
handleSelected = true;
}
else if ((e.X > rightMiddle.X) && (e.X < rightMiddle.X + rightMiddle.Width) && (e.Y > rightMiddle.Y) && (e.Y < rightMiddle.Y + rightMiddle.Height))
{
this.Cursor = Cursors.SizeWE;
rightMiddleSelected = true;
handleSelected = true;
}
else if ((e.X > rcSelect.X) && (e.X < rcSelect.X + rcSelect.Width) && (e.Y > rcSelect.Y) && (e.Y < rcSelect.Y + rcSelect.Height))
{
this.Cursor = Cursors.SizeAll;
rectangleSelected = true;
handleSelected = true;
}
else
{
this.Cursor = Cursors.Cross;
topLeftSelected = false;
topMiddleSelected = false;
topRightSelected = false;
bottomLeftSelected = false;
bottomMiddleSelected = false;
bottomRightSelected = false;
leftMiddleSelected = false;
rightMiddleSelected = false;
rectangleSelected = false;
handleSelected = false;
}
// Start the snip on mouse down
if (e.Button != MouseButtons.Left) return;
if (handleSelected == true) return;
pntStart = e.Location;
oldRcSelect = rcSelect;
rcSelect = new Rectangle(e.Location, new Size(0, 0));
lbl.Visible = true;
lbl.Location = new Point(e.X + 10, e.Y + 10); ;
lbl.Value = string.Format("0x0");
lbl.Refresh();
oldX = e.X;
oldY = e.Y;
this.Refresh();
}
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
private void RefreshOnMove()
{
var rc = oldRcSelect;
rc.Inflate(3, 3);
Invalidate(rc);
rc = rcSelect;
rc.Inflate(3, 3);
Invalidate(rc);
Update();
}
protected override void OnMouseMove(MouseEventArgs e)
{
oldRcSelect = rcSelect;
// Modify the selection on mouse move
if ((e.X > topLeft.X) && (e.X < topLeft.X + topLeft.Width) && (e.Y > topLeft.Y) && (e.Y < topLeft.Y + topLeft.Height))
{
this.Cursor = Cursors.SizeNWSE;
}
else if ((e.X > topMiddle.X) && (e.X < topMiddle.X + topMiddle.Width) && (e.Y > topMiddle.Y) && (e.Y < topMiddle.Y + topMiddle.Height))
{
this.Cursor = Cursors.SizeNS;
}
else if ((e.X > topRight.X) && (e.X < topRight.X + topRight.Width) && (e.Y > topRight.Y) && (e.Y < topRight.Y + topRight.Height))
{
this.Cursor = Cursors.SizeNESW;
}
else if ((e.X > bottomLeft.X) && (e.X < bottomLeft.X + bottomLeft.Width) && (e.Y > bottomLeft.Y) && (e.Y < bottomLeft.Y + bottomLeft.Height))
{
this.Cursor = Cursors.SizeNESW;
}
else if ((e.X > bottomMiddle.X) && (e.X < bottomMiddle.X + bottomMiddle.Width) && (e.Y > bottomMiddle.Y) && (e.Y < bottomMiddle.Y + bottomMiddle.Height))
{
this.Cursor = Cursors.SizeNS;
}
else if ((e.X > bottomRight.X) && (e.X < bottomRight.X + bottomRight.Width) && (e.Y > bottomRight.Y) && (e.Y < bottomRight.Y + bottomRight.Height))
{
this.Cursor = Cursors.SizeNWSE;
}
else if ((e.X > leftMiddle.X) && (e.X < leftMiddle.X + leftMiddle.Width) && (e.Y > leftMiddle.Y) && (e.Y < leftMiddle.Y + leftMiddle.Height))
{
this.Cursor = Cursors.SizeWE;
}
else if ((e.X > rightMiddle.X) && (e.X < rightMiddle.X + rightMiddle.Width) && (e.Y > rightMiddle.Y) && (e.Y < rightMiddle.Y + rightMiddle.Height))
{
this.Cursor = Cursors.SizeWE;
}
else if ((e.X > rcSelect.X) && (e.X < rcSelect.X + rcSelect.Width) && (e.Y > rcSelect.Y) && (e.Y < rcSelect.Y + rcSelect.Height))
{
this.Cursor = Cursors.SizeAll;
}
else
{
this.Cursor = Cursors.Cross;
}
if (e.Button == MouseButtons.Left && handleSelected == true)
{
Rectangle backupRect = rcSelect;
if (topLeftSelected == true)
{
rcSelect.X += e.X - oldX;
rcSelect.Width -= e.X - oldX;
rcSelect.Y += e.Y - oldY;
rcSelect.Height -= e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (topRightSelected == true)
{
rcSelect.Width += e.X - oldX;
rcSelect.Y += e.Y - oldY;
rcSelect.Height -= e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (topMiddleSelected == true)
{
rcSelect.Y += e.Y - oldY;
rcSelect.Height -= e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (bottomLeftSelected == true)
{
rcSelect.Width -= e.X - oldX;
rcSelect.X += e.X - oldX;
rcSelect.Height += e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (bottomMiddleSelected == true)
{
rcSelect.Height += e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (bottomRightSelected == true)
{
rcSelect.Width += e.X - oldX;
rcSelect.Height += e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (rightMiddleSelected == true)
{
rcSelect.Width += e.X - oldX;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (leftMiddleSelected == true)
{
rcSelect.X += e.X - oldX;
rcSelect.Width -= e.X - oldX;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
else if (rectangleSelected == true)
{
rcSelect.X = rcSelect.X + e.X - oldX;
rcSelect.Y = rcSelect.Y + e.Y - oldY;
lbl.Location = new Point(rcSelect.X, rcSelect.Y - 25);
lbl.Value = string.Format("{0}x{1}", rcSelect.Width, rcSelect.Height);
this.RefreshOnMove();
}
}
else if (e.Button == MouseButtons.Left)
{
int x1 = Math.Min(e.X, pntStart.X);
int y1 = Math.Min(e.Y, pntStart.Y);
int x2 = Math.Max(e.X, pntStart.X);
int y2 = Math.Max(e.Y, pntStart.Y);
rcSelect = new Rectangle(x1, y1, x2 - x1, y2 - y1);
this.RefreshOnMove();
lbl.Location = new Point(x1, y1 - 25);
lbl.Value = string.Format("{0}x{1}", x2 - x1, y2 - y1);
lbl.Refresh();
}
oldX = e.X;
oldY = e.Y;
}
protected override void OnMouseUp(MouseEventArgs e)
{
// Complete the snip on mouse-up
if (rcSelect.Width <= 0 || rcSelect.Height <= 0) return;
Image = new Bitmap(rcSelect.Width, rcSelect.Height);
using (Graphics gr = Graphics.FromImage(Image))
{
gr.DrawImage(this.BackgroundImage, new Rectangle(0, 0, Image.Width, Image.Height),
rcSelect, GraphicsUnit.Pixel);
}
topLeftSelected = false;
topMiddleSelected = false;
topRightSelected = false;
bottomLeftSelected = false;
bottomMiddleSelected = false;
bottomRightSelected = false;
leftMiddleSelected = false;
rightMiddleSelected = false;
rectangleSelected = false;
handleSelected = false;
//DialogResult = DialogResult.OK;
}
protected override void OnPaint(PaintEventArgs e)
{
// Draw the current selection
using (Brush br = new SolidBrush(Color.FromArgb(30, Color.Black)))
{
int x1 = rcSelect.X; int x2 = rcSelect.X + rcSelect.Width;
int y1 = rcSelect.Y; int y2 = rcSelect.Y + rcSelect.Height;
e.Graphics.FillRectangle(br, new Rectangle(0, 0, x1, this.Height));
e.Graphics.FillRectangle(br, new Rectangle(x2, 0, this.Width - x2, this.Height));
e.Graphics.FillRectangle(br, new Rectangle(x1, 0, x2 - x1, y1));
e.Graphics.FillRectangle(br, new Rectangle(x1, y2, x2 - x1, this.Height - y2));
}
using (Pen pen = new Pen(Color.Red, 1))
{
e.Graphics.DrawRectangle(pen, rcSelect);
}
//Resize Controls
//Top left
topLeft = new Rectangle(rcSelect.X - 3, rcSelect.Y - 3, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, topLeft);
}
//Top middle
topMiddle = new Rectangle((rcSelect.X - 3) + (rcSelect.Width) / 2, rcSelect.Y - 3, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, topMiddle);
}
//Top right
topRight = new Rectangle((rcSelect.X - 3) + rcSelect.Width, rcSelect.Y - 3, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, topRight);
}
//Bottom left
bottomLeft = new Rectangle(rcSelect.X - 3, (rcSelect.Y - 3) + rcSelect.Height, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, bottomLeft);
}
//Bottom middle
bottomMiddle = new Rectangle((rcSelect.X - 3) + (rcSelect.Width) / 2, (rcSelect.Y - 3) + rcSelect.Height, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, bottomMiddle);
}
//Bottom right
bottomRight = new Rectangle((rcSelect.X - 3) + rcSelect.Width, (rcSelect.Y - 3) + rcSelect.Height, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, bottomRight);
}
//Left middle
leftMiddle = new Rectangle(rcSelect.X - 3, (rcSelect.Y - 3) + (rcSelect.Height) / 2, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, leftMiddle);
}
//Right middle
rightMiddle = new Rectangle((rcSelect.X - 3) + rcSelect.Width, (rcSelect.Y - 3) + (rcSelect.Height) / 2, 6, 6);
using (Brush br = new SolidBrush(Color.FromArgb(200, Color.Red)))
{
e.Graphics.FillRectangle(br, rightMiddle);
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// Allow canceling the snip with the Escape key
if (keyData == Keys.Escape) this.DialogResult = DialogResult.Cancel;
return base.ProcessCmdKey(ref msg, keyData);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment