Files
AX-Copilot-Codex/src/AxCopilot/Views/EyeDropperWindow.xaml.cs

136 lines
4.0 KiB
C#

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace AxCopilot.Views;
/// <summary>
/// 전체 화면 스포이드 모드. 마우스를 따라다니는 돋보기와 HEX 코드를 표시하고,
/// 클릭 시 해당 픽셀 색상을 캡처하여 ColorPickResultWindow를 표시합니다.
/// </summary>
public partial class EyeDropperWindow : Window
{
[DllImport("user32.dll")]
private static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("gdi32.dll")]
private static extern uint GetPixel(IntPtr hdc, int x, int y);
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[StructLayout(LayoutKind.Sequential)]
private struct POINT { public int X, Y; }
/// <summary>클릭으로 선택된 색상. null이면 취소.</summary>
public System.Drawing.Color? PickedColor { get; private set; }
public double PickX { get; private set; }
public double PickY { get; private set; }
private readonly System.Drawing.Rectangle _screenBounds;
public EyeDropperWindow()
{
InitializeComponent();
// 전체 모니터 영역
_screenBounds = GetAllScreenBounds();
Left = _screenBounds.X;
Top = _screenBounds.Y;
Width = _screenBounds.Width;
Height = _screenBounds.Height;
Loaded += (_, _) =>
{
Magnifier.Visibility = Visibility.Visible;
HexLabel.Visibility = Visibility.Visible;
};
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
var pos = e.GetPosition(RootCanvas);
var color = GetScreenPixelColor();
// 돋보기 위치 (커서 오른쪽 위)
Canvas.SetLeft(Magnifier, pos.X + 16);
Canvas.SetTop(Magnifier, pos.Y - 100);
// HEX 레이블 위치
Canvas.SetLeft(HexLabel, pos.X + 16);
Canvas.SetTop(HexLabel, pos.Y - 10);
// 돋보기 색상 미리보기
var wpfColor = System.Windows.Media.Color.FromRgb(color.R, color.G, color.B);
MagPreview.Fill = new SolidColorBrush(wpfColor);
HexLabelText.Text = $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
PickedColor = GetScreenPixelColor();
GetCursorPos(out var pt);
PickX = pt.X;
PickY = pt.Y;
Close();
}
else if (e.ChangedButton == MouseButton.Right)
{
PickedColor = null;
Close();
}
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
PickedColor = null;
Close();
}
}
private static System.Drawing.Color GetScreenPixelColor()
{
GetCursorPos(out var pt);
var hdc = GetDC(IntPtr.Zero);
try
{
uint pixel = GetPixel(hdc, pt.X, pt.Y);
int r = (int)(pixel & 0xFF);
int g = (int)((pixel >> 8) & 0xFF);
int b = (int)((pixel >> 16) & 0xFF);
return System.Drawing.Color.FromArgb(r, g, b);
}
finally
{
ReleaseDC(IntPtr.Zero, hdc);
}
}
private static System.Drawing.Rectangle GetAllScreenBounds()
{
int left = 0, top = 0, right = 0, bottom = 0;
foreach (var screen in System.Windows.Forms.Screen.AllScreens)
{
var b = screen.Bounds;
left = Math.Min(left, b.Left);
top = Math.Min(top, b.Top);
right = Math.Max(right, b.Right);
bottom = Math.Max(bottom, b.Bottom);
}
return new System.Drawing.Rectangle(left, top, right - left, bottom - top);
}
}