You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
7.9 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GeoSigma
{
public partial class FrmPicker : Form
{
PictureBox pictureBox;
Bitmap bmp;
Graphics g;
bool isDown = false;
Point downPoint;
Rectangle rect;
Pen pen;
Bitmap bmpZoom;
Graphics zoom;
int zoomSize = 0;
Color selectedColor = Color.White;
public Color SelectedColor
{
get { return selectedColor; }
set { selectedColor = value; }
}
public FrmPicker()
{
InitializeComponent();
pictureBox = new PictureBox();
pictureBox.Dock = DockStyle.Fill;
pictureBox.BorderStyle = BorderStyle.None;
pictureBox.MouseUp += new MouseEventHandler(pictureBox_MouseUp);
pictureBox.MouseMove += new MouseEventHandler(pictureBox_MouseMove);
pictureBox.Cursor = Cursors.Cross;
this.Controls.Add(pictureBox);
this.Size = new Size(0, 0);
this.DoubleBuffered = true;
bmpZoom = new Bitmap(picZoom.Width, picZoom.Height);
zoom = Graphics.FromImage(bmpZoom);
picZoom.Image?.Dispose();
picZoom.Image = bmpZoom;
pen = new Pen(Color.Black, 1);
pen.DashCap = DashCap.Round;
pen.DashStyle = DashStyle.Dash;
zoomSize = tckZoomSize.Value;
pictureBox.PreviewKeyDown += PictureBox_PreviewKeyDown;
}
private void PictureBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
//throw new NotImplementedException();
}
private void FrmPicker_Load(object sender, EventArgs e)
{
rect = new Rectangle(0, 0, 0, 0);
//Screen[] scrs = Screen.AllScreens;
//for(int i = 0; i < scrs.Length; i++)
//{
// Rectangle recCur = scrs[i].Bounds;
// if (recCur.Right > rect.Right)
// {
// rect.Width += (recCur.Right- rect.Right);
// }
// if(recCur.Bottom> rect.Bottom)
// {
// rect.Height += (recCur.Bottom - rect.Bottom);
// }
//}
RefreshActualScreens();
foreach(MonitorInfo screen in ActualScreens)
{
Rectangle recCur = screen.Bounds;
if (recCur.Right > rect.Right)
{
rect.Width += (recCur.Right - rect.Right);
}
if (recCur.Bottom > rect.Bottom)
{
rect.Height += (recCur.Bottom - rect.Bottom);
}
}
bmp = new Bitmap(rect.Width, rect.Height);
g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 0, rect.Size);
pictureBox.Image?.Dispose();
pictureBox.Image = bmp;
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Normal;
this.Bounds = rect;
//Point pt = this.PointToScreen(this.Owner.Location);
//MessageBox.Show(this.Owner.Location.ToString() + "\r\n" + pt.ToString());
}
void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
Point mousePoint = Control.MousePosition;
lblXValue.Text = mousePoint.X.ToString();
lblYValue.Text = mousePoint.Y.ToString();
Color color = bmp.GetPixel(mousePoint.X, mousePoint.Y);
lblShowColor.BackColor = color;
txtColorValue.Text = string.Format("{0:d},{1:d},{2:d}"
, color.R
, color.G
, color.B);
zoom.InterpolationMode = InterpolationMode.NearestNeighbor;
zoom.DrawImage(bmp, new Rectangle(0, 0, bmpZoom.Width, bmpZoom.Height),
Control.MousePosition.X - bmpZoom.Width / (2 * zoomSize),
Control.MousePosition.Y - bmpZoom.Height / (2 * zoomSize),
bmpZoom.Width / zoomSize, bmpZoom.Height / zoomSize,
GraphicsUnit.Pixel);
zoom.DrawLine(pen, picZoom.Width / 2 - 1, 0, picZoom.Width / 2 - 1, picZoom.Height);
zoom.DrawLine(pen, 0, picZoom.Height / 2 - 1, picZoom.Width, picZoom.Height / 2 - 1);
picZoom.Refresh();
}
void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button != MouseButtons.Left)
{
CancelForm();
return;
}
selectedColor = bmp.GetPixel(e.Location.X, e.Location.Y);
pen.Dispose();
bmp.Dispose();
bmpZoom.Dispose();
zoom.Dispose();
g.Dispose();
this.DialogResult = DialogResult.OK;
Close();
}
private void CancelForm()
{
this.DialogResult = DialogResult.Cancel;
pen.Dispose();
bmp.Dispose();
bmpZoom.Dispose();
zoom.Dispose();
g.Dispose();
this.Close();
}
private void pnlColorWindow_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDown = true;
downPoint = e.Location;
}
}
private void pnlColorWindow_MouseMove(object sender, MouseEventArgs e)
{
if (isDown)
{
pnlColorWindow.Left = Control.MousePosition.X - downPoint.X;
pnlColorWindow.Top = Control.MousePosition.Y - downPoint.Y;
}
}
private void pnlColorWindow_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDown = false;
}
}
private void tckZoomSize_ValueChanged(object sender, EventArgs e)
{
zoomSize = tckZoomSize.Value;
}
private void FrmPicker_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar == (char)Keys.Escape)
{
CancelForm();
}
}
public static List<MonitorInfo> ActualScreens = new List<MonitorInfo>();
public static void RefreshActualScreens()
{
ActualScreens.Clear();
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref Rect prect, int d) =>
{
ActualScreens.Add(new MonitorInfo()
{
Bounds = new Rectangle()
{
X = prect.left,
Y = prect.top,
Width = prect.right - prect.left,
Height = prect.bottom - prect.top,
},
IsPrimary = (prect.left == 0) && (prect.top == 0),
});
return true;
};
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0);
}
[DllImport("user32")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);
[StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
}
public class MonitorInfo
{
public bool IsPrimary = false;
public Rectangle Bounds = new Rectangle();
}
}