GdiPlusHelper.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Runtime.Versioning;
  4. namespace Ryujinx.Common.SystemInterop
  5. {
  6. [SupportedOSPlatform("windows")]
  7. public static partial class GdiPlusHelper
  8. {
  9. private const string LibraryName = "gdiplus.dll";
  10. private static readonly IntPtr _initToken;
  11. static GdiPlusHelper()
  12. {
  13. CheckStatus(GdiplusStartup(out _initToken, StartupInputEx.Default, out _));
  14. }
  15. private static void CheckStatus(int gdiStatus)
  16. {
  17. if (gdiStatus != 0)
  18. {
  19. throw new Exception($"GDI Status Error: {gdiStatus}");
  20. }
  21. }
  22. private struct StartupInputEx
  23. {
  24. public int GdiplusVersion;
  25. #pragma warning disable CS0649
  26. public IntPtr DebugEventCallback;
  27. public int SuppressBackgroundThread;
  28. public int SuppressExternalCodecs;
  29. public int StartupParameters;
  30. #pragma warning restore CS0649
  31. public static StartupInputEx Default => new StartupInputEx
  32. {
  33. // We assume Windows 8 and upper
  34. GdiplusVersion = 2,
  35. DebugEventCallback = IntPtr.Zero,
  36. SuppressBackgroundThread = 0,
  37. SuppressExternalCodecs = 0,
  38. StartupParameters = 0,
  39. };
  40. }
  41. private struct StartupOutput
  42. {
  43. public IntPtr NotificationHook;
  44. public IntPtr NotificationUnhook;
  45. }
  46. [LibraryImport(LibraryName)]
  47. private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output);
  48. [LibraryImport(LibraryName)]
  49. private static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics);
  50. [LibraryImport(LibraryName)]
  51. private static partial int GdipDeleteGraphics(IntPtr graphics);
  52. [LibraryImport(LibraryName)]
  53. private static partial int GdipGetDpiX(IntPtr graphics, out float dpi);
  54. public static float GetDpiX(IntPtr hwnd)
  55. {
  56. CheckStatus(GdipCreateFromHWND(hwnd, out IntPtr graphicsHandle));
  57. CheckStatus(GdipGetDpiX(graphicsHandle, out float result));
  58. CheckStatus(GdipDeleteGraphics(graphicsHandle));
  59. return result;
  60. }
  61. }
  62. }