CursorUtil.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:CursorUtil
  3. * 作者:xulisong
  4. * 创建时间: 2019/4/17 9:14:22
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Windows.Input;
  15. using System.Windows.Interop;
  16. using System.Windows.Media.Imaging;
  17. using FWindSoft.WindowsApi;
  18. namespace FWindSoft.Wpf.Utils
  19. {
  20. public class CursorUtil
  21. {
  22. public static Cursor CreateCursor(Stream stream)
  23. {
  24. //StreamResourceInfo sri = Application.GetResourceStream(new Uri(@"Resources/0036.cur", UriKind.Relative));
  25. Cursor cursor = new Cursor(stream);
  26. return cursor;
  27. }
  28. /// <summary>
  29. /// 识别.ani和.cur文件
  30. /// </summary>
  31. /// <param name="path"></param>
  32. /// <returns></returns>
  33. public static Cursor CreateCursor(string path)
  34. {
  35. Cursor cursor = new Cursor(path);
  36. return cursor;
  37. }
  38. #region 自定义方式创建
  39. /// <summary>
  40. /// 根据 BitmapImage 创建鼠标图标
  41. /// </summary>
  42. /// <param name="bs">鼠标图像</param>
  43. /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>
  44. /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>
  45. /// <returns>错误则返回null</returns>
  46. public static Cursor CreateCursor(BitmapSource bs, uint xHotSpot = 0, uint yHotSpot = 0)
  47. {
  48. Cursor ret = null;
  49. Bitmap bm = BitmapSourceToBitmap(bs);
  50. if (bm != null)
  51. {
  52. try
  53. {
  54. ret = InternalCreateCursor(bm, xHotSpot, yHotSpot);
  55. }
  56. catch (Exception)
  57. {
  58. ret = null;
  59. }
  60. }
  61. return ret;
  62. }
  63. /// <summary>
  64. /// 根据 Bitmap 创建自定义鼠标
  65. /// </summary>
  66. /// <param name="bm">鼠标图像</param>
  67. /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>
  68. /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>
  69. /// <returns>错误则返回null</returns>
  70. public static Cursor CreateCursor(Bitmap bm, uint xHotSpot = 0, uint yHotSpot = 0)
  71. {
  72. Cursor ret = null;
  73. if (bm == null)
  74. {
  75. return ret;
  76. }
  77. try
  78. {
  79. ret = InternalCreateCursor(bm, xHotSpot, yHotSpot);
  80. }
  81. catch (Exception)
  82. {
  83. ret = null;
  84. }
  85. return ret;
  86. }
  87. /// <summary>
  88. /// 根据 本地文件路径 创建鼠标图标
  89. /// </summary>
  90. /// <param name="filePath">鼠标图像全路径</param>
  91. /// <param name="xHotSpot">焦点在图片中的 X轴 坐标(相对于左上角)</param>
  92. /// <param name="yHotSpot">焦点在图片中的 Y轴 坐标(相对于左上角)</param>
  93. /// <returns>错误则返回null</returns>
  94. public static Cursor CreateCursor(String filePath, uint xHotSpot = 0, uint yHotSpot = 0)
  95. {
  96. Cursor ret = null;
  97. if (string.IsNullOrWhiteSpace(filePath) || Directory.Exists(filePath) || !File.Exists(filePath))
  98. {
  99. return ret;
  100. }
  101. //首先尝试通过默认方法创建
  102. if (filePath.EndsWith(".ani") || filePath.EndsWith(".cur"))
  103. {
  104. try
  105. {
  106. ret = new Cursor(filePath);
  107. }
  108. catch (Exception)
  109. {
  110. ret = null;
  111. }
  112. }
  113. if (ret == null)
  114. {
  115. Bitmap bmp = null;
  116. try
  117. {
  118. bmp = Bitmap.FromFile(filePath) as Bitmap;
  119. if (bmp != null)
  120. {
  121. ret = CreateCursor(bmp, xHotSpot, yHotSpot);
  122. }
  123. }
  124. catch (Exception)
  125. {
  126. ret = null;
  127. }
  128. }
  129. return ret;
  130. }
  131. /// <summary>
  132. /// BitmapSource 转 Bitmap
  133. /// </summary>
  134. /// <param name="bi"></param>
  135. /// <returns>错误则返回null</returns>
  136. public static Bitmap BitmapSourceToBitmap(BitmapSource bi)
  137. {
  138. Bitmap ret = null;
  139. if (bi == null)
  140. {
  141. return ret;
  142. }
  143. using (MemoryStream stream = new MemoryStream())
  144. {
  145. try
  146. {
  147. BmpBitmapEncoder enc = new BmpBitmapEncoder();
  148. enc.Frames.Add(BitmapFrame.Create(bi));
  149. enc.Save(stream);
  150. ret = new Bitmap(stream);
  151. }
  152. catch (Exception)
  153. {
  154. ret = null;
  155. }
  156. }
  157. return ret;
  158. }
  159. /// <summary>
  160. /// 创建鼠标(本方法不允许public,避免内存泄漏)
  161. /// </summary>
  162. /// <param name="bitmap"></param>
  163. /// <param name="xHotSpot"></param>
  164. /// <param name="yHotSpot"></param>
  165. /// <returns></returns>
  166. protected static Cursor InternalCreateCursor(Bitmap bitmap, uint xHotSpot, uint yHotSpot)
  167. {
  168. var iconInfo = new IconInfo();
  169. WinAPI.GetIconInfo(bitmap.GetHicon(), ref iconInfo);
  170. iconInfo.xHotspot = xHotSpot;//焦点x轴坐标
  171. iconInfo.yHotspot = yHotSpot;//焦点y轴坐标
  172. iconInfo.fIcon = false;//设置鼠标
  173. TSafeHandle cursorHandle = WinAPI.CreateIconIndirect(ref iconInfo);
  174. cursorHandle.Release = (h) => WinAPI.DestroyIcon(h);
  175. return CursorInteropHelper.Create(cursorHandle);
  176. }
  177. #endregion
  178. }
  179. }