C# 自定义并动态切换光标

本文经原作者授权以原创方式二次分享,欢迎转载、分享。

原文作者:唐宋元明清的博客

原文地址:https://www.cnblogs.com/kybs0/p/14873136.html

系统有很多光标类型 :Cursors 类 (System.Windows.Input) | Microsoft Docs[1]

本章介绍如何自定义光标、并动态切换光标类型。

动态切换光标类型

  • 以白板书写为例:

    • 鼠标操作时Cursor为红点;

    • 触摸时Cursor为空;

public MainWindow()
    {
        InitializeComponent();
        MouseEnter += (s, e) =>
        {
            ShowMouseCursor(e);
        };
        MouseMove += (s, e) =>
        {
            ShowMouseCursor(e);
        };
        StylusMove += (s, e) =>
        {
            ShowNoneCursor();
        };
    }
  • 设置光标显示;

private void ShowNoneCursor()
  {
      if (Cursor == Cursors.None)
      {
          return;
      }
      Cursor = Cursors.None;
      Mouse.UpdateCursor();
  }
  private void ShowMouseCursor(MouseEventArgs e)
  {
      if (e.StylusDevice != null && e.StylusDevice.Id > -1)
      {
          return;
      }
      if (Cursor == GetFillCursor())
      {
          return;
      }
      Cursor = GetFillCursor();
      Mouse.UpdateCursor();
  }
  private Cursor _fillCursor = null;
  private Cursor GetFillCursor()
  {
      return _fillCursor ?? (_fillCursor = CursorHelper.CreateFillCursor());
  }

触摸书写时,会有个默认光标,所以此处把触摸时的光标置空Cursors.None;

Mouse.UpdateCursor()能强制更新光标。当然,不调用这个更新方法肉眼其实也看不出啥。。。

7b5645392a6dc5c9096d8a79b7471afa.gif

光标切换效果如上,前面一段是用鼠标书写,后面是触摸书写,光标类型有切换。红点光标自定义方案见下方。

 自定义光标1)自定义一个纯色的圆形光标

public static Cursor CreateFillCursor(int size = 24, Brush fillBrush = null)
    {
        int unitSize = size / 4;
        var bmp = new Bitmap(size, size);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.Clip = new Region(new Rectangle(0, 0, size, size));
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            using (var pen = new Pen(fillBrush ?? Brushes.Red, unitSize))
            {

                g.DrawEllipse(pen, new Rectangle(unitSize, unitSize, unitSize, unitSize));
            }
        }
        return BitmapCursor.CreateBmpCursor(bmp);
    }

2)也可以通过图片资源BitmapSource来生成光标;

public static Cursor CreateFromBitmapSource(BitmapSource source)
   {
       var bitmap = BitmapSourceToBitmap(source);
       return BitmapCursor.CreateBmpCursor(bitmap);
   }
   private static Bitmap BitmapSourceToBitmap(BitmapSource source)
   {
       using (var stream = new MemoryStream())
       {
           var e = new BmpBitmapEncoder();
           e.Frames.Add(BitmapFrame.Create(source));
           e.Save(stream);

           var bmp = new Bitmap(stream);

           return bmp;
       }
   }

2)BitmapCursor类;

internal class BitmapCursor : SafeHandle
   {
       public override bool IsInvalid => handle == (IntPtr)(-1);

       public static Cursor CreateBmpCursor(Bitmap cursorBitmap)
       {

           var c = new BitmapCursor(cursorBitmap);

           return CursorInteropHelper.Create(c);
       }
       protected BitmapCursor(Bitmap cursorBitmap)
           : base((IntPtr)(-1), true)
       {
           handle = cursorBitmap.GetHicon();
       }
       protected override bool ReleaseHandle()
       {
           bool result = DestroyIcon(handle);

           handle = (IntPtr)(-1);

           return result;
       }
       [DllImport("user32")]
       private static extern bool DestroyIcon(IntPtr hIcon);
   }

参考资料:
WPF 自定义鼠标光标 - DH_青叶 - 博客园[2]
[WPF]自定义鼠标指针 - 周银辉 - 博客园[3]

参考资料

[1]

Cursors 类 (System.Windows.Input) | Microsoft Docs: https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.input.cursors?view=net-5.0

[2]

WPF 自定义鼠标光标 - DH_青叶 - 博客园: https://www.cnblogs.com/dhqy/p/7754176.html

[3]

[WPF]自定义鼠标指针 - 周银辉 - 博客园: https://www.cnblogs.com/zhouyinhui/archive/2010/05/28/1746502.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值