Files
better-genshin-impact/Build/MicaSetup/Helper/Device/DpiHelper.cs

76 lines
2.4 KiB
C#

using MicaSetup.Natives;
using System;
using System.Windows.Interop;
using Application = System.Windows.Application;
namespace MicaSetup.Helper;
public static class DpiHelper
{
public static float ScaleX => GetScale().X;
public static float ScaleY => GetScale().Y;
private static DpiScaleF GetScale()
{
if (OsVersionHelper.IsWindows81_OrGreater && Application.Current?.MainWindow != null)
{
nint hwnd = new WindowInteropHelper(Application.Current?.MainWindow).Handle;
nint hMonitor = User32.MonitorFromWindow(hwnd, MonitorFlags.MONITOR_DEFAULTTONEAREST);
SHCore.GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out uint dpiX, out uint dpiY);
return new DpiScaleF(dpiX / 96f, dpiY / 96f);
}
nint hdc = User32.GetDC(0);
float scaleX = Gdi32.GetDeviceCaps(hdc, DeviceCap.LOGPIXELSX);
float scaleY = Gdi32.GetDeviceCaps(hdc, DeviceCap.LOGPIXELSY);
User32.ReleaseDC(0, hdc);
return new(scaleX / 96f, scaleY / 96f);
}
public static double CalcDPI(double src) => Math.Ceiling(src * ScaleX);
public static float CalcDPI(float src) => (float)Math.Ceiling(src * ScaleX);
public static double CalcDPIX(double src) => Math.Ceiling(src * ScaleX);
public static float CalcDPIX(float src) => (float)Math.Ceiling(src * ScaleX);
public static double CalcDPIY(double src) => Math.Ceiling(src * ScaleY);
public static float CalcDPIY(float src) => (float)Math.Ceiling(src * ScaleY);
public static double CalcDPi(double src) => Math.Ceiling(src * (1d / ScaleX));
public static float CalcDPi(float src) => (float)Math.Ceiling(src * (1f / ScaleX));
public static double CalcDPiX(double src) => Math.Ceiling(src * (1d / ScaleX));
public static float CalcDPiX(float src) => (float)Math.Ceiling(src * (1f / ScaleX));
public static double CalcDPiY(double src) => Math.Ceiling(src * (1d / ScaleY));
public static float CalcDPiY(float src) => (float)Math.Ceiling(src * (1f / ScaleY));
}
internal readonly struct DpiScaleF
{
private readonly float x;
public float X => x;
private readonly float y;
public float Y => y;
public DpiScaleF(float x = 1f, float y = 1f)
{
this.x = x;
this.y = y;
}
public DpiScaleF Reserve()
{
return new DpiScaleF(1f / x, 1f / y);
}
public override string ToString() => $"{X},{Y}";
}