zoukankan      html  css  js  c++  java
  • C# 自定义并动态切换光标

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

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

    动态切换光标类型

    以白板书写为例:鼠标操作时,Cursor为红点;触摸时,Cursor为空;

     1     public MainWindow()
     2     {
     3         InitializeComponent();
     4         MouseEnter += (s, e) =>
     5         {
     6             ShowMouseCursor(e);
     7         };
     8         MouseMove += (s, e) =>
     9         {
    10             ShowMouseCursor(e);
    11         };
    12         StylusMove += (s, e) =>
    13         {
    14             ShowNoneCursor();
    15         };
    16     }

    设置光标显示:

     1     private void ShowNoneCursor()
     2     {
     3         if (Cursor == Cursors.None)
     4         {
     5             return;
     6         }
     7         Cursor = Cursors.None;
     8         Mouse.UpdateCursor();
     9     }
    10     private void ShowMouseCursor(MouseEventArgs e)
    11     {
    12         if (e.StylusDevice != null && e.StylusDevice.Id > -1)
    13         {
    14             return;
    15         }
    16         if (Cursor == GetFillCursor())
    17         {
    18             return;
    19         }
    20         Cursor = GetFillCursor();
    21         Mouse.UpdateCursor();
    22     }
    23     private Cursor _fillCursor = null;
    24     private Cursor GetFillCursor()
    25     {
    26         return _fillCursor ?? (_fillCursor = CursorHelper.CreateFillCursor());
    27     }

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

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

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

    自定义光标

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

     1     public static Cursor CreateFillCursor(int size = 24, Brush fillBrush = null)
     2     {
     3         int unitSize = size / 4;
     4         var bmp = new Bitmap(size, size);
     5         using (Graphics g = Graphics.FromImage(bmp))
     6         {
     7             g.Clip = new Region(new Rectangle(0, 0, size, size));
     8             g.SmoothingMode = SmoothingMode.HighQuality;
     9             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    10             using (var pen = new Pen(fillBrush ?? Brushes.Red, unitSize))
    11             {
    12 
    13                 g.DrawEllipse(pen, new Rectangle(unitSize, unitSize, unitSize, unitSize));
    14             }
    15         }
    16         return BitmapCursor.CreateBmpCursor(bmp);
    17     }

    也可以通过图片资源BitmapSource来生成光标:

     1     public static Cursor CreateFromBitmapSource(BitmapSource source)
     2     {
     3         var bitmap = BitmapSourceToBitmap(source);
     4         return BitmapCursor.CreateBmpCursor(bitmap);
     5     }
     6     private static Bitmap BitmapSourceToBitmap(BitmapSource source)
     7     {
     8         using (var stream = new MemoryStream())
     9         {
    10             var e = new BmpBitmapEncoder();
    11             e.Frames.Add(BitmapFrame.Create(source));
    12             e.Save(stream);
    13 
    14             var bmp = new Bitmap(stream);
    15 
    16             return bmp;
    17         }
    18     }

    BitmapCursor:

     1     internal class BitmapCursor : SafeHandle
     2     {
     3         public override bool IsInvalid => handle == (IntPtr)(-1);
     4 
     5         public static Cursor CreateBmpCursor(Bitmap cursorBitmap)
     6         {
     7 
     8             var c = new BitmapCursor(cursorBitmap);
     9 
    10             return CursorInteropHelper.Create(c);
    11         }
    12         protected BitmapCursor(Bitmap cursorBitmap)
    13             : base((IntPtr)(-1), true)
    14         {
    15             handle = cursorBitmap.GetHicon();
    16         }
    17         protected override bool ReleaseHandle()
    18         {
    19             bool result = DestroyIcon(handle);
    20 
    21             handle = (IntPtr)(-1);
    22 
    23             return result;
    24         }
    25         [DllImport("user32")]
    26         private static extern bool DestroyIcon(IntPtr hIcon);
    27     }
    View Code

    博客参考:

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    PHP serialize() 函数
    PHP print_r() 函数
  • 原文地址:https://www.cnblogs.com/kybs0/p/14873136.html
Copyright © 2011-2022 走看看