Archive Browser
Download Cyotek.Windows.Forms.ColorPicker-1.0.2.0.zip version 1.0.2.0, last updated 13/07/2013 (382.27 KB)
Download- md5: 34597ba8a4143a1794524236d9f43524
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
// Cyotek Color Picker controls library
// Copyright © 2013 Cyotek. All Rights Reserved.
// http://cyotek.com/blog/tag/colorpicker
// If you use this code in your applications, donations or attribution are welcome
/// <summary>
/// Represents a control that allows the selection of a color by dragging the mouse across the desktop
/// </summary>
[DefaultProperty("Color")]
[DefaultEvent("ColorChanged")]
public class ScreenColorPicker : Control, IColorEditor
{
#region Instance Fields
private Color _color;
private Cursor _eyedropperCursor;
private Color _gridColor;
private Image _image;
private bool _showGrid;
private bool _showTextWithSnapshot;
private int _zoom;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScreenColorPicker"/> class.
/// </summary>
public ScreenColorPicker()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.Selectable | ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
this.UpdateStyles();
this.Zoom = 8;
this.Color = Color.Empty;
this.ShowTextWithSnapshot = false;
this.TabStop = false;
this.TabIndex = 0;
this.ShowGrid = true;
this.GridColor = SystemColors.ControlDark;
}
#endregion
#region Events
/// <summary>
/// Occurs when the Color property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ColorChanged;
/// <summary>
/// Occurs when the GridColor property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler GridColorChanged;
/// <summary>
/// Occurs when the Image property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ImageChanged;
/// <summary>
/// Occurs when the ShowGrid property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ShowGridChanged;
/// <summary>
/// Occurs when the ShowTextWithSnapshot property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ShowTextWithSnapshotChanged;
/// <summary>
/// Occurs when the Zoom property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ZoomChanged;
#endregion
#region Overridden Members
/// <summary>
/// Releases the unmanaged resources used by the <see cref="T:System.Windows.Forms.Control" /> and its child controls and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_eyedropperCursor != null)
_eyedropperCursor.Dispose();
if (SnapshotImage != null)
SnapshotImage.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.FontChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
this.Invalidate();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.ForeColorChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnForeColorChanged(EventArgs e)
{
base.OnForeColorChanged(e);
this.Invalidate();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && !this.IsCapturing)
{
if (_eyedropperCursor == null)
// ReSharper disable AssignNullToNotNullAttribute
_eyedropperCursor = new Cursor(this.GetType().Assembly.GetManifestResourceStream(string.Concat(this.GetType().Namespace, ".Resources.eyedropper.cur")));
// ReSharper restore AssignNullToNotNullAttribute
this.Cursor = _eyedropperCursor;
this.IsCapturing = true;
this.Invalidate();
}
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseMove" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsCapturing)
this.UpdateSnapshot();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (this.IsCapturing)
{
this.Cursor = Cursors.Default;
this.IsCapturing = false;
this.Invalidate();
}
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
base.OnPaintBackground(e); // HACK: Easiest way of supporting things like BackgroundImage, BackgroundImageLayout etc
// draw the current snapshot, if present
if (this.SnapshotImage != null)
{
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.DrawImage(this.SnapshotImage, new Rectangle(0, 0, this.SnapshotImage.Width * this.Zoom, this.SnapshotImage.Height * this.Zoom), new Rectangle(Point.Empty, this.SnapshotImage.Size), GraphicsUnit.Pixel);
}
this.PaintAdornments(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Resize" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.CreateSnapshotImage();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.TextChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.Invalidate();
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the component color.
/// </summary>
/// <value>The component color.</value>
[Category("Behavior")]
[DefaultValue(typeof(Color), "Empty")]
public virtual Color Color
{
get { return _color; }
set
{
if (this.Color != value)
{
_color = value;
this.OnColorChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the color of the grid.
/// </summary>
/// <value>The color of the grid.</value>
[Category("Appearance")]
[DefaultValue(typeof(Color), "ControlDark")]
public virtual Color GridColor
{
get { return _gridColor; }
set
{
if (this.GridColor != value)
{
_gridColor = value;
this.OnGridColorChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Returns if a snapshot image is available
/// </summary>
/// <value><c>true</c> if a snapshot image is available; otherwise, <c>false</c>.</value>
[Browsable(false)]
public bool HasSnapshot { get; protected set; }
/// <summary>
/// Gets or sets the image.
/// </summary>
/// <value>The image.</value>
[Category("Appearance")]
[DefaultValue(typeof(Image), null)]
public virtual Image Image
{
get { return _image; }
set
{
if (this.Image != value)
{
_image = value;
this.OnImageChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether a pixel grid is displayed.
/// </summary>
/// <value><c>true</c> if a pixel grid is displayed; otherwise, <c>false</c>.</value>
[Category("Appearance")]
[DefaultValue(true)]
public virtual bool ShowGrid
{
get { return _showGrid; }
set
{
if (this.ShowGrid != value)
{
_showGrid = value;
this.OnShowGridChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether text should be shown when a snapshot is present.
/// </summary>
/// <value><c>true</c> if text is to be shown when a snapshot is present; otherwise, <c>false</c> to only show text when no snapshot is available.</value>
[Category("Appearance")]
[DefaultValue(false)]
public virtual bool ShowTextWithSnapshot
{
get { return _showTextWithSnapshot; }
set
{
if (this.ShowTextWithSnapshot != value)
{
_showTextWithSnapshot = value;
this.OnShowTextWithSnapshotChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the tab order of the control within its container.
/// </summary>
/// <value>The index of the tab.</value>
/// <returns>The index value of the control within the set of controls within its container. The controls in the container are included in the tab order.</returns>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DefaultValue(0)]
public new int TabIndex
{
get { return base.TabIndex; }
set { base.TabIndex = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the user can give the focus to this control using the TAB key.
/// </summary>
/// <value><c>true</c> if [tab stop]; otherwise, <c>false</c>.</value>
/// <returns>true if the user can give the focus to the control using the TAB key; otherwise, false. The default is true.Note:This property will always return true for an instance of the <see cref="T:System.Windows.Forms.Form" /> class.</returns>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DefaultValue(false)]
public new bool TabStop
{
get { return base.TabStop; }
set { base.TabStop = value; }
}
/// <summary>
/// Gets or sets the zoom level of the snapshot image.
/// </summary>
/// <value>The zoom level.</value>
[Category("Appearance")]
[DefaultValue(8)]
public virtual int Zoom
{
get { return _zoom; }
set
{
if (this.Zoom != value)
{
_zoom = value;
this.OnZoomChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets a value indicating snapshot capture is in progress.
/// </summary>
/// <value><c>true</c> if snapshot capture is in progress; otherwise, <c>false</c>.</value>
protected bool IsCapturing { get; set; }
/// <summary>
/// Gets or sets a value indicating whether redraw operations should occur.
/// </summary>
/// <value><c>true</c> if redraw operations should occur; otherwise, <c>false</c>.</value>
protected bool LockUpdates { get; set; }
/// <summary>
/// Gets or sets the snapshot image.
/// </summary>
/// <value>The snapshot image.</value>
protected Bitmap SnapshotImage { get; set; }
#endregion
#region Members
/// <summary>
/// Creates the snapshot image.
/// </summary>
protected virtual void CreateSnapshotImage()
{
Size size;
if (this.SnapshotImage != null)
{
this.SnapshotImage.Dispose();
this.SnapshotImage = null;
}
size = this.GetSnapshotSize();
if (!size.IsEmpty)
{
this.SnapshotImage = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);
this.Invalidate();
}
}
/// <summary>
/// Gets the center point based on the current zoom level.
/// </summary>
protected virtual Point GetCenterPoint()
{
int x;
int y;
x = (this.ClientSize.Width / this.Zoom) / 2;
y = (this.ClientSize.Height / this.Zoom) / 2;
return new Point(x, y);
}
/// <summary>
/// Gets the size of the snapshot.
/// </summary>
protected virtual Size GetSnapshotSize()
{
int snapshotWidth;
int snapshotHeight;
snapshotWidth = (int)Math.Ceiling(this.ClientSize.Width / (double)this.Zoom);
snapshotHeight = (int)Math.Ceiling(this.ClientSize.Height / (double)this.Zoom);
return snapshotHeight != 0 && snapshotWidth != 0 ? new Size(snapshotWidth, snapshotHeight) : Size.Empty;
}
/// <summary>
/// Raises the <see cref="ColorChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnColorChanged(EventArgs e)
{
EventHandler handler;
handler = this.ColorChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Raises the <see cref="GridColorChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnGridColorChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = this.GridColorChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Raises the <see cref="ImageChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnImageChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = this.ImageChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Raises the <see cref="ShowGridChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnShowGridChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = this.ShowGridChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Raises the <see cref="ShowTextWithSnapshotChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnShowTextWithSnapshotChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = this.ShowTextWithSnapshotChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Raises the <see cref="ZoomChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnZoomChanged(EventArgs e)
{
EventHandler handler;
this.CreateSnapshotImage();
handler = this.ZoomChanged;
if (handler != null)
handler(this, e);
}
/// <summary>
/// Paints adornments onto the control.
/// </summary>
/// <param name="e">The <see cref="PaintEventArgs"/> instance containing the event data.</param>
protected virtual void PaintAdornments(PaintEventArgs e)
{
// grid
if (this.ShowGrid)
this.PaintGrid(e);
// center marker
if (this.HasSnapshot)
this.PaintCenterMarker(e);
// image
if (this.Image != null && (!this.HasSnapshot || this.ShowTextWithSnapshot))
e.Graphics.DrawImage(this.Image, (this.ClientSize.Width - this.Image.Size.Width) / 2, (this.ClientSize.Height - this.Image.Size.Height) / 2);
// draw text
if (!string.IsNullOrEmpty(this.Text) && (!this.HasSnapshot || this.ShowTextWithSnapshot))
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.ClientRectangle, this.ForeColor, this.BackColor, TextFormatFlags.ExpandTabs | TextFormatFlags.NoPrefix | TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.WordBreak | TextFormatFlags.WordEllipsis);
}
/// <summary>
/// Paints the center marker.
/// </summary>
/// <param name="e">The <see cref="PaintEventArgs"/> instance containing the event data.</param>
protected virtual void PaintCenterMarker(PaintEventArgs e)
{
Point center;
center = this.GetCenterPoint();
using (Pen pen = new Pen(this.ForeColor))
e.Graphics.DrawRectangle(pen, center.X * this.Zoom, center.Y * this.Zoom, this.Zoom + 2, this.Zoom + 2);
}
/// <summary>
/// Paints the pixel grid.
/// </summary>
/// <param name="e">The <see cref="PaintEventArgs"/> instance containing the event data.</param>
protected virtual void PaintGrid(PaintEventArgs e)
{
Rectangle viewport;
int pixelSize;
pixelSize = this.Zoom;
viewport = this.ClientRectangle;
using (Pen pen = new Pen(this.GridColor)
{
DashStyle = DashStyle.Dot
})
{
for (int x = viewport.Left + 1; x < viewport.Right; x += pixelSize)
e.Graphics.DrawLine(pen, x, viewport.Top, x, viewport.Bottom);
for (int y = viewport.Top + 1; y < viewport.Bottom; y += pixelSize)
e.Graphics.DrawLine(pen, viewport.Left, y, viewport.Right, y);
e.Graphics.DrawRectangle(pen, viewport);
}
}
/// <summary>
/// Updates the snapshot.
/// </summary>
protected virtual void UpdateSnapshot()
{
Point cursor;
cursor = MousePosition;
cursor.X -= this.SnapshotImage.Width / 2;
cursor.Y -= this.SnapshotImage.Height / 2;
using (Graphics graphics = Graphics.FromImage(this.SnapshotImage))
{
Point center;
// clear the image first, in case the mouse is near the borders of the screen so there isn't enough copy content to fill the area
graphics.Clear(Color.Empty);
// copy the image from the screen
graphics.CopyFromScreen(cursor, Point.Empty, this.SnapshotImage.Size);
// update the active color
center = this.GetCenterPoint();
this.Color = this.SnapshotImage.GetPixel(center.X, center.Y);
// force a redraw
this.HasSnapshot = true;
this.Refresh(); // just calling Invalidate isn't enough as the display will lag
}
}
#endregion
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate