2022-05-20 15:39:52 +08:00
|
|
|
|
using GeekDesk.Interface;
|
|
|
|
|
|
using GeekDesk.Util;
|
|
|
|
|
|
using HandyControl.Controls;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
using System.Windows.Controls.Primitives;
|
2022-08-30 09:06:27 +08:00
|
|
|
|
using System.Windows.Forms;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
|
using System.Windows.Interop;
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
using System.Windows.Media.Imaging;
|
2024-08-08 10:56:00 +08:00
|
|
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
2022-08-30 09:06:27 +08:00
|
|
|
|
using Cursors = System.Windows.Input.Cursors;
|
|
|
|
|
|
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
|
|
|
|
|
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
|
|
|
|
|
namespace GeekDesk.Control.Windows
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// ColorPickerWindow.xaml 的交互逻辑
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public partial class PixelColorPickerWindow : IWindowCommon
|
|
|
|
|
|
{
|
2024-08-08 10:56:00 +08:00
|
|
|
|
private static int PIXEL_REC_LENGTH = 10;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
|
|
|
|
|
private static readonly int MIN_LENGTH = 10;
|
|
|
|
|
|
private static readonly int MAX_LENGTH = 50;
|
|
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
//private static System.Drawing.Bitmap bgBitmap;
|
|
|
|
|
|
|
|
|
|
|
|
private static RenderTargetBitmap renderTargetBitmap;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
|
|
|
|
|
private readonly ColorPicker colorPicker;
|
|
|
|
|
|
|
2022-08-30 09:06:27 +08:00
|
|
|
|
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
|
|
|
|
|
private static extern bool SetProcessDPIAware();
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
public PixelColorPickerWindow(ColorPicker colorPicker)
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
this.colorPicker = colorPicker;
|
2022-09-02 11:30:08 +08:00
|
|
|
|
|
2022-09-01 15:23:44 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProcessDPIAware();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e) { }
|
2022-05-20 15:39:52 +08:00
|
|
|
|
ColorPickerWindow_Init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ColorPickerWindow_Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
this.WindowState = WindowState.Normal;//还原窗口(非最小化和最大化)
|
|
|
|
|
|
|
2023-01-29 16:11:54 +08:00
|
|
|
|
var screens = Screen.AllScreens;
|
|
|
|
|
|
int allWidth = 0;
|
|
|
|
|
|
int allHeight = 0;
|
|
|
|
|
|
int x = 0;
|
|
|
|
|
|
int y = 0;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
2023-01-29 16:11:54 +08:00
|
|
|
|
|
|
|
|
|
|
foreach (var screen in screens)
|
|
|
|
|
|
{
|
|
|
|
|
|
var rect = screen.Bounds;
|
|
|
|
|
|
allWidth += rect.Width;
|
|
|
|
|
|
allHeight += rect.Height;
|
|
|
|
|
|
x = Math.Min(x, rect.X);
|
|
|
|
|
|
y = Math.Min(y, rect.Y);
|
|
|
|
|
|
}
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
//获取缩放比例
|
|
|
|
|
|
double scale = ScreenUtil.GetScreenScalingFactor();
|
2024-08-08 10:56:00 +08:00
|
|
|
|
|
2023-01-29 16:11:54 +08:00
|
|
|
|
|
|
|
|
|
|
this.Width = allWidth;
|
|
|
|
|
|
this.Height = allHeight;
|
|
|
|
|
|
|
|
|
|
|
|
this.Left = x;
|
|
|
|
|
|
this.Top = y;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
|
|
|
|
|
DesktopBG.Width = this.Width;
|
|
|
|
|
|
DesktopBG.Height = this.Height;
|
|
|
|
|
|
this.Topmost = true;
|
|
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
System.Drawing.Bitmap bgBitmap = new System.Drawing.Bitmap(
|
2022-08-30 09:06:27 +08:00
|
|
|
|
(int)(Width * scale),
|
|
|
|
|
|
(int)(Height * scale),
|
2022-05-20 15:39:52 +08:00
|
|
|
|
System.Drawing.Imaging.PixelFormat.Format32bppArgb
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bgBitmap))
|
|
|
|
|
|
{
|
|
|
|
|
|
g.CopyFromScreen(
|
2023-01-29 16:11:54 +08:00
|
|
|
|
(int)this.Left,
|
|
|
|
|
|
(int)this.Top,
|
2022-05-20 15:39:52 +08:00
|
|
|
|
0,
|
|
|
|
|
|
0,
|
|
|
|
|
|
bgBitmap.Size
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
BitmapSource bs = Imaging.CreateBitmapSourceFromHBitmap(
|
|
|
|
|
|
bgBitmap.GetHbitmap(),
|
|
|
|
|
|
IntPtr.Zero,
|
|
|
|
|
|
Int32Rect.Empty,
|
|
|
|
|
|
BitmapSizeOptions.FromEmptyOptions()
|
|
|
|
|
|
);
|
2022-05-23 17:52:35 +08:00
|
|
|
|
DesktopBG.Source = bs;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
VisualBrush b = (VisualBrush)PixelBG.Fill;
|
|
|
|
|
|
b.Visual = DesktopBG;
|
|
|
|
|
|
Mouse.OverrideCursor = Cursors.Cross;
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建一个RenderTargetBitmap,捕获窗口的内容
|
|
|
|
|
|
renderTargetBitmap = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32);
|
|
|
|
|
|
renderTargetBitmap.Render(this);
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
SetPixelAbout(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
public void OnKeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (e.Key == Key.Escape)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.DataContext = null;
|
|
|
|
|
|
this.Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
2022-05-23 17:52:35 +08:00
|
|
|
|
Mouse.OverrideCursor = null;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
Point pos = e.MouseDevice.GetPosition(DesktopBG);
|
2024-08-08 08:41:42 +08:00
|
|
|
|
colorPicker.SelectedBrush = new SolidColorBrush(GetColorAtPosition(Mouse.GetPosition(this)));
|
2022-05-20 15:39:52 +08:00
|
|
|
|
this.Close();
|
|
|
|
|
|
ClickColorPickerToggleButton(colorPicker);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ClickColorPickerToggleButton(ColorPicker colorPicker)
|
|
|
|
|
|
{
|
|
|
|
|
|
const BindingFlags InstanceBindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
|
|
|
|
Type type = colorPicker.GetType();
|
|
|
|
|
|
FieldInfo fi = type.GetField("_toggleButtonDropper", InstanceBindFlags);
|
|
|
|
|
|
|
|
|
|
|
|
ToggleButton tb = (ToggleButton)fi.GetValue(colorPicker);
|
|
|
|
|
|
if (tb != null && tb.IsChecked == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
tb.IsChecked = false;
|
|
|
|
|
|
MethodInfo mi = type.GetMethod("ToggleButtonDropper_Click", InstanceBindFlags);
|
|
|
|
|
|
mi.Invoke(colorPicker, new object[] { null, null });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-08-30 09:06:27 +08:00
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
SetPixelAbout(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
|
|
|
|
public static extern bool DeleteObject(IntPtr onj);
|
|
|
|
|
|
|
2024-08-08 10:56:00 +08:00
|
|
|
|
|
|
|
|
|
|
// Constants for DPI
|
|
|
|
|
|
private const int HORZRES = 8;
|
|
|
|
|
|
private const int VERTRES = 10;
|
|
|
|
|
|
private const int LOGPIXELSX = 88;
|
|
|
|
|
|
private const int LOGPIXELSY = 90;
|
|
|
|
|
|
private static float GetDpi(bool isX)
|
|
|
|
|
|
{
|
|
|
|
|
|
IntPtr hdc = WindowUtil.GetDC(IntPtr.Zero);
|
|
|
|
|
|
int dpi = isX ? WindowUtil.GetDeviceCaps(hdc, LOGPIXELSX) : WindowUtil.GetDeviceCaps(hdc, LOGPIXELSY);
|
|
|
|
|
|
WindowUtil.ReleaseDC(IntPtr.Zero, hdc);
|
|
|
|
|
|
return dpi / 96f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
private void SetPixelAbout(MouseEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
VisualBrush b = (VisualBrush)PixelBG.Fill;
|
|
|
|
|
|
|
2024-08-08 10:56:00 +08:00
|
|
|
|
Point pos = Mouse.GetPosition(this);
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
Rect viewBox = b.Viewbox;
|
|
|
|
|
|
|
|
|
|
|
|
viewBox.Width = PIXEL_REC_LENGTH;
|
|
|
|
|
|
viewBox.Height = PIXEL_REC_LENGTH;
|
|
|
|
|
|
|
|
|
|
|
|
viewBox.X = pos.X - PIXEL_REC_LENGTH / 2;
|
|
|
|
|
|
viewBox.Y = pos.Y - PIXEL_REC_LENGTH / 2;
|
|
|
|
|
|
b.Viewbox = viewBox;
|
|
|
|
|
|
|
|
|
|
|
|
double x = pos.X + 10;
|
|
|
|
|
|
double y = pos.Y + 10;
|
2024-08-08 10:56:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取缩放比例
|
|
|
|
|
|
double scale = ScreenUtil.GetScreenScalingFactor();
|
|
|
|
|
|
if (x + ColorCanvas.Width > this.Width / scale)
|
2022-05-20 15:39:52 +08:00
|
|
|
|
{
|
|
|
|
|
|
x = pos.X - ColorCanvas.Width - 10;
|
|
|
|
|
|
}
|
2024-08-08 10:56:00 +08:00
|
|
|
|
if (y + ColorCanvas.Height > this.Height / scale)
|
2022-05-20 15:39:52 +08:00
|
|
|
|
{
|
|
|
|
|
|
y = pos.Y - ColorCanvas.Height - 10;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-08 10:56:00 +08:00
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
Canvas.SetLeft(ColorCanvas, x);
|
|
|
|
|
|
Canvas.SetTop(ColorCanvas, y);
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Color wColor = GetColorAtPosition(pos);
|
|
|
|
|
|
|
|
|
|
|
|
System.Drawing.Color dColor = System.Drawing.Color.FromArgb(wColor.A, wColor.R, wColor.G, wColor.B);
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
PixelColor_HTML.Text = "#" + dColor.Name.ToUpper().Substring(2);
|
2022-05-20 15:39:52 +08:00
|
|
|
|
PixelColor_RGB.Text = dColor.R + "," + dColor.G + "," + dColor.B;
|
2024-08-08 08:41:42 +08:00
|
|
|
|
Pixel_XY.Text = (int)pos.X + "*" + (int)pos.Y;
|
2022-05-20 15:39:52 +08:00
|
|
|
|
|
|
|
|
|
|
SolidColorBrush scb = (SolidColorBrush)PixelColor.Fill;
|
2024-08-08 08:41:42 +08:00
|
|
|
|
scb.Color = wColor;
|
|
|
|
|
|
//scb.Color = Color.FromArgb(dColor.A, dColor.R, dColor.G, dColor.B);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Color GetColorAtPosition(Point position)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 使用CroppedBitmap裁剪出鼠标位置的一个像素
|
|
|
|
|
|
CroppedBitmap croppedBitmap = new CroppedBitmap(renderTargetBitmap, new Int32Rect((int)position.X, (int)position.Y, 1, 1));
|
|
|
|
|
|
// 将像素数据复制到数组中
|
|
|
|
|
|
byte[] pixels = new byte[4];
|
|
|
|
|
|
croppedBitmap.CopyPixels(pixels, 4, 0);
|
|
|
|
|
|
// 如果像素数据有效,则返回颜色
|
|
|
|
|
|
//if (pixels.Length == 4)
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
return Color.FromArgb(pixels[3], pixels[2], pixels[1], pixels[0]);
|
|
|
|
|
|
//return Color.FromArgb(0, 0, 0, 0);
|
2022-05-20 15:39:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 滚轮控制缩放区域
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender"></param>
|
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
|
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (e.Delta < 0 && PIXEL_REC_LENGTH < MAX_LENGTH)
|
|
|
|
|
|
{
|
|
|
|
|
|
//缩小
|
|
|
|
|
|
PIXEL_REC_LENGTH += 5;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (e.Delta > 0 && PIXEL_REC_LENGTH > MIN_LENGTH)
|
|
|
|
|
|
{
|
|
|
|
|
|
//放大
|
|
|
|
|
|
PIXEL_REC_LENGTH -= 5;
|
|
|
|
|
|
}
|
|
|
|
|
|
SetPixelAbout(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-30 09:06:27 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 右键按下
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender"></param>
|
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
|
private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
2022-09-01 15:23:44 +08:00
|
|
|
|
Mouse.OverrideCursor = null;
|
2022-08-30 09:06:27 +08:00
|
|
|
|
GlobalColorPickerWindow.ShowOrHide();
|
|
|
|
|
|
//关闭
|
|
|
|
|
|
this.Close();
|
|
|
|
|
|
}
|
2024-08-08 08:41:42 +08:00
|
|
|
|
|
2022-05-20 15:39:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|