WPF 自定义鼠标指针图片

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. //DllImport  
  6. using System.Runtime.InteropServices;  
  7. //SecurityPermission  
  8. using System.Security.Permissions;  
  9. //SafeHandleZeroOrMinusOneIsInvalid  
  10. using Microsoft.Win32.SafeHandles;  
  11. //Cursor  
  12. using System.Windows.Input;  
  13. //UIElement  
  14. using System.Windows;  
  15. //RenderTargetBitmap  
  16. using System.Windows.Media.Imaging;  
  17. //PixelFormats  
  18. using System.Windows.Media;  
  19. //MemoryStream  
  20. using System.IO;  
  21. //CursorInteropHelper  
  22. using System.Windows.Interop;  
  23. //Bitmap  
  24. using System.Drawing;  
  25.   
  26. namespace _WPF自定义鼠标指针  
  27. {  
  28.     public class CursorHelper  
  29.     {  
  30.   
  31.         //公有:  
  32.   
  33.   
  34.         //创建鼠标指针方法:  
  35.   
  36.         /// <summary>  
  37.         /// 根据 BitmapImage 创建鼠标图标  
  38.         /// </summary>  
  39.         /// <param name="bs">鼠标图像</param>  
  40.         /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>  
  41.         /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>  
  42.         /// <returns>错误则返回null</returns>  
  43.         public static Cursor CreateCursor(BitmapSource bs, uint xHotSpot = 0, uint yHotSpot = 0)  
  44.         {  
  45.             Cursor ret = null;  
  46.   
  47.             Bitmap bm = BitmapSource2Bitmap(bs);  
  48.             if (bm != null)  
  49.             {  
  50.                 try  
  51.                 {  
  52.                     ret = InternalCreateCursor(bm, xHotSpot, yHotSpot);  
  53.                 }  
  54.                 catch (Exception)  
  55.                 {  
  56.                     ret = null;  
  57.                 }  
  58.             }  
  59.   
  60.             return ret;  
  61.         }  
  62.   
  63.         /// <summary>  
  64.         /// 根据 本地文件路径 创建鼠标图标  
  65.         /// </summary>  
  66.         /// <param name="filePath">鼠标图像全路径</param>  
  67.         /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>  
  68.         /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>  
  69.         /// <returns>错误则返回null</returns>  
  70.         public static Cursor CreateCursor(String filePath, uint xHotSpot = 0, uint yHotSpot = 0)  
  71.         {  
  72.             Cursor ret = null;  
  73.   
  74.             if (string.IsNullOrWhiteSpace(filePath) || Directory.Exists(filePath) || !File.Exists(filePath))  
  75.             {  
  76.                 return ret;  
  77.             }  
  78.   
  79.             //首先尝试通过默认方法创建  
  80.             if (filePath.EndsWith(".ani") || filePath.EndsWith(".cur"))  
  81.             {  
  82.                 try  
  83.                 {  
  84.                     ret = new Cursor(filePath);  
  85.                 }  
  86.                 catch (Exception)  
  87.                 {  
  88.                     ret = null;  
  89.                 }  
  90.             }  
  91.   
  92.             //如果文件不是正确的.ani或.cur文件,则尝试通过BitMap创建  
  93.             if (ret == null)  
  94.             {  
  95.   
  96.                 Bitmap bmp = null;  
  97.                 try  
  98.                 {  
  99.                     bmp = Bitmap.FromFile(filePath) as Bitmap;  
  100.                     if (bmp != null)  
  101.                     {  
  102.                         ret = CreateCursor(bmp, xHotSpot, yHotSpot);  
  103.                     }  
  104.                 }  
  105.                 catch (Exception)  
  106.                 {  
  107.                     ret = null;  
  108.                 }  
  109.             }  
  110.   
  111.             return ret;  
  112.         }  
  113.   
  114.         /// <summary>  
  115.         /// 根据 Bitmap 创建自定义鼠标  
  116.         /// </summary>  
  117.         /// <param name="bm">鼠标图像</param>  
  118.         /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>  
  119.         /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>  
  120.         /// <returns>错误则返回null</returns>  
  121.         public static Cursor CreateCursor(Bitmap bm, uint xHotSpot = 0, uint yHotSpot = 0)  
  122.         {  
  123.             Cursor ret = null;  
  124.   
  125.             if (bm == null)  
  126.             {  
  127.                 return ret;  
  128.             }  
  129.   
  130.             try  
  131.             {  
  132.                 ret = InternalCreateCursor(bm, xHotSpot, yHotSpot);  
  133.             }  
  134.             catch (Exception)  
  135.             {  
  136.                 ret = null;  
  137.             }  
  138.   
  139.             return ret;  
  140.         }  
  141.   
  142.   
  143.         //BitmapSource 转 Bitmap 方法  
  144.   
  145.         /// <summary>  
  146.         /// BitmapSource 转 Bitmap  
  147.         /// </summary>  
  148.         /// <param name="bi"></param>  
  149.         /// <returns>错误则返回null</returns>  
  150.         public static Bitmap BitmapSource2Bitmap(BitmapSource bi)  
  151.         {  
  152.   
  153.             Bitmap ret = null;  
  154.             MemoryStream stream = null;  
  155.   
  156.             if (bi == null)  
  157.             {  
  158.                 return ret;  
  159.             }  
  160.   
  161.             try  
  162.             {  
  163.                 stream = new MemoryStream();  
  164.                 BmpBitmapEncoder enc = new BmpBitmapEncoder();  
  165.                 enc.Frames.Add(BitmapFrame.Create(bi));  
  166.                 enc.Save(stream);  
  167.   
  168.                 ret = new Bitmap(stream);  
  169.             }  
  170.             catch (Exception)  
  171.             {  
  172.                 ret = null;  
  173.             }  
  174.             finally  
  175.             {  
  176.                 stream.Dispose();  
  177.             }  
  178.   
  179.             return ret;  
  180.         }  
  181.   
  182.   
  183.   
  184.         //保护:  
  185.   
  186.         /// <summary>  
  187.         /// 创建鼠标(本方法不允许public,避免内存泄漏)  
  188.         /// </summary>  
  189.         /// <param name="bitmap"></param>  
  190.         /// <param name="xHotSpot"></param>  
  191.         /// <param name="yHotSpot"></param>  
  192.         /// <returns></returns>  
  193.         protected static Cursor InternalCreateCursor(Bitmap bitmap, uint xHotSpot, uint yHotSpot)  
  194.         {  
  195.             var iconInfo = new NativeMethods.IconInfo;  
  196.             NativeMethods.GetIconInfo(bitmap.GetHicon(), ref iconInfo);  
  197.   
  198.             iconInfo.xHotspot = xHotSpot;//焦点x轴坐标  
  199.             iconInfo.yHotspot = yHotSpot;//焦点y轴坐标  
  200.             iconInfo.fIcon = false;//设置鼠标  
  201.   
  202.             SafeIconHandle cursorHandle = NativeMethods.CreateIconIndirect(ref iconInfo);  
  203.             return CursorInteropHelper.Create(cursorHandle);  
  204.         }  
  205.   
  206.         protected static class NativeMethods  
  207.         {  
  208.             public struct IconInfo  
  209.             {  
  210.                 public bool fIcon;  
  211.                 public uint xHotspot;  
  212.                 public uint yHotspot;  
  213.                 public IntPtr hbmMask;  
  214.                 public IntPtr hbmColor;  
  215.             }  
  216.   
  217.             [DllImport("user32.dll")]  
  218.             public static extern SafeIconHandle CreateIconIndirect(ref IconInfo icon);  
  219.   
  220.             [DllImport("user32.dll")]  
  221.             public static extern bool DestroyIcon(IntPtr hIcon);  
  222.   
  223.             [DllImport("user32.dll")]  
  224.             [return: MarshalAs(UnmanagedType.Bool)]  
  225.             public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);  
  226.         }  
  227.   
  228.         [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]  
  229.         protected class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid  
  230.         {  
  231.             public SafeIconHandle()  
  232.                 : base(true)  
  233.             {  
  234.             }  
  235.   
  236.             /// <summary>  
  237.             /// 释放资源  
  238.             /// </summary>  
  239.             /// <returns></returns>  点击打开链接
  240.             protected override bool ReleaseHandle()  
  241.             {  
  242.                 return NativeMethods.DestroyIcon(handle);  
  243.             }  
  244.         }  
  245.   
  246.     }  
  247. }  
  248. 原文链接:https://blog.csdn.net/hjnth/article/details/56483935

猜你喜欢

转载自blog.csdn.net/lhdsjhuang/article/details/79759175
今日推荐