CursorFactory.cs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using Avalonia.Win32.Interop;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using Avalonia.Input;
  10. using Avalonia.Platform;
  11. using System.Runtime.InteropServices;
  12. namespace Avalonia.Win32
  13. {
  14. internal class CursorFactory : IStandardCursorFactory
  15. {
  16. public static CursorFactory Instance { get; } = new CursorFactory();
  17. private CursorFactory()
  18. {
  19. }
  20. static CursorFactory()
  21. {
  22. LoadModuleCursor(StandardCursorType.DragMove, "ole32.dll", 2);
  23. LoadModuleCursor(StandardCursorType.DragCopy, "ole32.dll", 3);
  24. LoadModuleCursor(StandardCursorType.DragLink, "ole32.dll", 4);
  25. }
  26. private static void LoadModuleCursor(StandardCursorType cursorType, string module, int id)
  27. {
  28. IntPtr mh = UnmanagedMethods.GetModuleHandle(module);
  29. if (mh != IntPtr.Zero)
  30. {
  31. IntPtr cursor = UnmanagedMethods.LoadCursor(mh, new IntPtr(id));
  32. if (cursor != IntPtr.Zero)
  33. {
  34. PlatformHandle phCursor = new PlatformHandle(cursor, PlatformConstants.CursorHandleType);
  35. Cache.Add(cursorType, phCursor);
  36. }
  37. }
  38. }
  39. private static readonly Dictionary<StandardCursorType, int> CursorTypeMapping = new Dictionary
  40. <StandardCursorType, int>
  41. {
  42. {StandardCursorType.AppStarting, 32650},
  43. {StandardCursorType.Arrow, 32512},
  44. {StandardCursorType.Cross, 32515},
  45. {StandardCursorType.Hand, 32649},
  46. {StandardCursorType.Help, 32651},
  47. {StandardCursorType.Ibeam, 32513},
  48. {StandardCursorType.No, 32648},
  49. {StandardCursorType.SizeAll, 32646},
  50. {StandardCursorType.UpArrow, 32516},
  51. {StandardCursorType.SizeNorthSouth, 32645},
  52. {StandardCursorType.SizeWestEast, 32644},
  53. {StandardCursorType.Wait, 32514},
  54. //Same as SizeNorthSouth
  55. {StandardCursorType.TopSide, 32645},
  56. {StandardCursorType.BottomSize, 32645},
  57. //Same as SizeWestEast
  58. {StandardCursorType.LeftSide, 32644},
  59. {StandardCursorType.RightSide, 32644},
  60. //Using SizeNorthWestSouthEast
  61. {StandardCursorType.TopLeftCorner, 32642},
  62. {StandardCursorType.BottomRightCorner, 32642},
  63. //Using SizeNorthEastSouthWest
  64. {StandardCursorType.TopRightCorner, 32643},
  65. {StandardCursorType.BottomLeftCorner, 32643},
  66. // Fallback, should have been loaded from ole32.dll
  67. {StandardCursorType.DragMove, 32516},
  68. {StandardCursorType.DragCopy, 32516},
  69. {StandardCursorType.DragLink, 32516},
  70. };
  71. private static readonly Dictionary<StandardCursorType, IPlatformHandle> Cache =
  72. new Dictionary<StandardCursorType, IPlatformHandle>();
  73. public IPlatformHandle GetCursor(StandardCursorType cursorType)
  74. {
  75. IPlatformHandle rv;
  76. if (!Cache.TryGetValue(cursorType, out rv))
  77. {
  78. Cache[cursorType] =
  79. rv =
  80. new PlatformHandle(
  81. UnmanagedMethods.LoadCursor(IntPtr.Zero, new IntPtr(CursorTypeMapping[cursorType])),
  82. PlatformConstants.CursorHandleType);
  83. }
  84. return rv;
  85. }
  86. }
  87. }