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; /// /// 전체 화면 스포이드 모드. 마우스를 따라다니는 돋보기와 HEX 코드를 표시하고, /// 클릭 시 해당 픽셀 색상을 캡처하여 ColorPickResultWindow를 표시합니다. /// 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; } /// 클릭으로 선택된 색상. null이면 취소. 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); } }