diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 9244da5064..9650c44bef 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -49,7 +49,6 @@ namespace Avalonia.Win32 public Win32Platform() { - SetDpiAwareness(); CreateMessageWindow(); _dispatcher = new Win32DispatcherImpl(_hwnd); } @@ -80,6 +79,9 @@ namespace Avalonia.Win32 public static void Initialize(Win32PlatformOptions options) { s_options = options; + + SetDpiAwareness(); + var renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60) : new DefaultRenderTimer(60); AvaloniaLocator.CurrentMutable @@ -264,12 +266,31 @@ namespace Avalonia.Win32 var user32 = LoadLibrary("user32.dll"); var method = GetProcAddress(user32, nameof(SetProcessDpiAwarenessContext)); + var dpiAwareness = Options.DpiAwareness; + if (method != IntPtr.Zero) { - if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) || - SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) + if (dpiAwareness == Win32DpiAwareness.Unaware) { - return; + if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE)) + { + return; + } + } + else if (dpiAwareness == Win32DpiAwareness.SystemDpiAware) + { + if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) + { + return; + } + } + else if (dpiAwareness == Win32DpiAwareness.PerMonitorDpiAware) + { + if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) || + SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) + { + return; + } } } @@ -278,11 +299,20 @@ namespace Avalonia.Win32 if (method != IntPtr.Zero) { - SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE); + var awareness = (dpiAwareness) switch + { + Win32DpiAwareness.Unaware => PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE, + Win32DpiAwareness.SystemDpiAware => PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE, + Win32DpiAwareness.PerMonitorDpiAware => PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE, + _ => PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE, + }; + + SetProcessDpiAwareness(awareness); return; } - SetProcessDPIAware(); + if (dpiAwareness != Win32DpiAwareness.Unaware) + SetProcessDPIAware(); } } } diff --git a/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs b/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs index bbb4c37d7e..eac18dc080 100644 --- a/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs +++ b/src/Windows/Avalonia.Win32/Win32PlatformOptions.cs @@ -25,6 +25,27 @@ public enum Win32RenderingMode Wgl = 3 } +/// +/// Represents the DPI Awareness for the application. +/// +public enum Win32DpiAwareness +{ + /// + /// The application is DPI unaware. + /// + Unaware, + + /// + /// The application is system DPI aware. It will query DPI once and will not adjust to new DPI changes + /// + SystemDpiAware, + + /// + /// The application is per-monitor DPI aware. It adjust its scale factor whenever DPI changes. + /// + PerMonitorDpiAware +} + /// /// Represents the Win32 window composition mode. /// @@ -137,4 +158,9 @@ public class Win32PlatformOptions /// and only accepts null or . /// public IPlatformGraphics? CustomPlatformGraphics { get; set; } + + /// + /// Gets or sets the application's DPI awareness. + /// + public Win32DpiAwareness DpiAwareness { get; set; } = Win32DpiAwareness.PerMonitorDpiAware; }