WPF写的取色器

本文介绍了如何使用C#和WindowsAPI开发一个简单的全局鼠标钩子,实现在点击按钮后捕获鼠标点击的颜色。作者分享了GlobalMouseHook类和ScreenColorPicker类的代码,以及XAML和C#代码片段,展示了如何将取到的颜色实时显示在控件上。
摘要由CSDN通过智能技术生成

昨天有个小伙子,在找取色器工具。我说,这个应该开发起来很简单,于是,摸了大约半个钟的鱼,开发了一个。现在我把源码和操作案例发出来,供有需要的大佬们玩。(功能过于单一和简单,但是能用)

2cef4bd89be9e1a9413e02f889f085b1.png

先创建GlobalMouseHook类,用于实现全局钩子

public class GlobalMouseHook
{
    private const int WH_MOUSE_LL = 14;
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int WM_LBUTTONUP = 0x0202;


    public event EventHandler<Point> MouseReleased;


    private LowLevelMouseProc _proc;
    private IntPtr _hookID = IntPtr.Zero;


    public GlobalMouseHook()
    {
        _proc = HookCallback;
    }


    public void SetHook()
    {
        _hookID = SetWindowsHookEx(WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
    }


    public void ReleaseHook()
    {
        UnhookWindowsHookEx(_hookID);
    }


    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0)
        {
            if (wParam == (IntPtr)WM_LBUTTONUP)
            {
                MSLLHOOKSTRUCT hookStruct = Marshal.PtrToStructure<MSLLHOOKSTRUCT>(lParam);
                MouseReleased?.Invoke(this, new Point(hookStruct.pt.x, hookStruct.pt.y));
            }
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }


    private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);


    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);


    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);


    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);


    private struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public uint mouseData;
        public uint flags;
        public uint time;
        public IntPtr dwExtraInfo;
    }


    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int x;
        public int y;
    }
}

再创建ScreenColorPicker类,用于获取鼠标点击屏幕区域的颜色

public class ScreenColorPicker
{
    [DllImport("user32.dll")]
    static extern IntPtr GetDC(IntPtr hWnd);


    [DllImport("user32.dll")]
    static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);


    [DllImport("gdi32.dll")]
    static extern uint GetPixel(IntPtr hDC, int x, int y);


    public static Color GetColorAt(int x, int y)
    {
        IntPtr deskDC = GetDC(IntPtr.Zero);
        uint colorCode = GetPixel(deskDC, x, y);
        ReleaseDC(IntPtr.Zero, deskDC);


        Color color = Color.FromArgb(255,
                                      (byte)(colorCode & 0x000000FF),
                                      (byte)((colorCode & 0x0000FF00) >> 8),
                                      (byte)((colorCode & 0x00FF0000) >> 16));
        return color;
    }
}

xaml主页代码:

<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
     <Label/>
     <Button Content="开始取色" Width="80" Background="AntiqueWhite" Click="Button_Click"></Button>
     <Label/>
     <TextBox x:Name="colorCodeLabel" Text="Color Code" HorizontalAlignment="Center" IsReadOnly="True" IsEnabled="True"/>
     <Label/>
     <Rectangle x:Name="colorDisplay" Height="100" Width="100" Stroke="Black" HorizontalAlignment="Center"/>
     <Label>点击按钮以后,鼠标点击任意地方,即可进行取色。</Label>
 </StackPanel>

效果图:

b19bb8c08ffda15c78765fe55c28cbe1.png

xaml.cs代码:

public partial class MainWindow : Window
 {


     private GlobalMouseHook _mouseHook;


     public MainWindow()
     {
         InitializeComponent();
     }


     private void MouseHook_MouseReleased(object sender, Point point)
     {
         Color color = ScreenColorPicker.GetColorAt((int)point.X, (int)point.Y);
         Dispatcher.Invoke(() =>
         {
             // 显示颜色代码
             string colorCode = $"#{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}";
             // TextBox用来显示颜色代码
             colorCodeLabel.Text = colorCode;


             // 用来展示颜色的Rectangle
             colorDisplay.Fill = new SolidColorBrush(color);
             if (_mouseHook != null)
             {
                 _mouseHook.ReleaseHook();
                 _mouseHook.MouseReleased -= MouseHook_MouseReleased;
                 _mouseHook = null;
             }
         });
     }


     protected override void OnClosed(EventArgs e)
     {
         base.OnClosed(e);
         if (_mouseHook != null)
         {
             _mouseHook.ReleaseHook();
             _mouseHook.MouseReleased -= MouseHook_MouseReleased;
         }
     }


     private void Button_Click(object sender, RoutedEventArgs e)
     {
         _mouseHook = new GlobalMouseHook();


         _mouseHook.MouseReleased += MouseHook_MouseReleased;
         _mouseHook.SetHook();
     }
 }

演示效果:

d5cdde572b7a34bda89f0f49a37cc6fe.png

点击按钮,我点击VS这个都沙绿背景,试验效果:

4c55c5f2fde677f0754b20484ecdffd2.png

豆沙绿颜色代码就显示到textbox里面,可以人工复制出去使用;矩形框可以复现鼠标刚才点击区域的颜色,进行预览。

就这么简单,没了。这个文章当做水一下了,如果有帮助,欢迎点赞、转发和再看,谢谢各位大佬围观。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值