From e742237d00803e0940cce96db9cbeb5de7caee3e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 2 Feb 2016 20:57:37 +0100 Subject: [PATCH] Use actual DPI for scaling factor. Doesn't change when DPI changes yet though. --- .../Perspex.Win32/Interop/UnmanagedMethods.cs | 20 +++++++++----- src/Windows/Perspex.Win32/Win32Platform.cs | 26 +++---------------- src/Windows/Perspex.Win32/WindowImpl.cs | 23 +++++++++++----- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs index e8ba9bab16..e75174012f 100644 --- a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs @@ -746,19 +746,27 @@ namespace Perspex.Win32.Interop public static extern void GetScaleFactorForMonitor(IntPtr hMon, out uint pScale); [DllImport("user32.dll")] - public static extern IntPtr MonitorFromPoint(POINT pt, uint dwFlags); + public static extern IntPtr MonitorFromPoint(POINT pt, MONITOR dwFlags); - public const uint MONITOR_DEFAULTTONULL = 0x00000000; - public const uint MONITOR_DEFAULTTOPRIMARY = 0x00000001; - public const uint MONITOR_DEFAULTTONEAREST = 0x00000002; + [DllImport("user32.dll")] + public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags); + + public enum MONITOR + { + MONITOR_DEFAULTTONULL = 0x00000000, + MONITOR_DEFAULTTOPRIMARY = 0x00000001, + MONITOR_DEFAULTTONEAREST = 0x00000002, + } - public enum PROCESS_DPI_AWARENESS { + public enum PROCESS_DPI_AWARENESS + { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } - public enum MONITOR_DPI_TYPE { + public enum MONITOR_DPI_TYPE + { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, diff --git a/src/Windows/Perspex.Win32/Win32Platform.cs b/src/Windows/Perspex.Win32/Win32Platform.cs index d23a74f911..f8e4f7d35d 100644 --- a/src/Windows/Perspex.Win32/Win32Platform.cs +++ b/src/Windows/Perspex.Win32/Win32Platform.cs @@ -22,16 +22,15 @@ namespace Perspex.Win32 { private static readonly Win32Platform s_instance = new Win32Platform(); private static Thread _uiThread; - private UnmanagedMethods.WndProc _wndProcDelegate; - private IntPtr _hwnd; - private double _scale = 1.0; private readonly List _delegates = new List(); public Win32Platform() { - HandleDpi(); + // Declare that this process is aware of per monitor DPI + UnmanagedMethods.SetProcessDpiAwareness(UnmanagedMethods.PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE); + CreateMessageWindow(); } @@ -40,8 +39,6 @@ namespace Perspex.Win32 UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDOUBLECLK)); public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(UnmanagedMethods.GetDoubleClickTime()); - public double RenderScalingFactor => _scale; - public double LayoutScalingFactor => _scale; public static void Initialize() { @@ -173,22 +170,5 @@ namespace Perspex.Win32 { return new PopupImpl(); } - - private void HandleDpi() - { - // Declare that this process is aware of per monitor DPI - UnmanagedMethods.SetProcessDpiAwareness(UnmanagedMethods.PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE); - - // Get the DPI for the main monitor, and set the scaling factor - UnmanagedMethods.POINT pt = new UnmanagedMethods.POINT() { X = 1, Y = 1 }; - var hMonitor = UnmanagedMethods.MonitorFromPoint(pt, UnmanagedMethods.MONITOR_DEFAULTTONEAREST); - - // TODO: Check for failure - uint dpix, dpiy; - UnmanagedMethods.GetDpiForMonitor(hMonitor, UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out dpix, out dpiy); - - // Set scale based on x DPI - _scale = dpix / 96.0; - } } } diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index f003c9a5a9..e16c5991f8 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -26,18 +26,13 @@ namespace Perspex.Win32 IntPtr.Zero, new IntPtr((int)UnmanagedMethods.Cursor.IDC_ARROW)); private UnmanagedMethods.WndProc _wndProcDelegate; - private string _className; - private IntPtr _hwnd; - private IInputRoot _owner; - private bool _trackingMouse; - private bool _isActive; - private bool _decorated = true; + private double _scaling = 1; public WindowImpl() { @@ -103,7 +98,7 @@ namespace Perspex.Win32 } } - public double Scaling => 1; + public double Scaling => _scaling; public IPlatformHandle Handle { @@ -562,6 +557,20 @@ namespace Perspex.Win32 } Handle = new PlatformHandle(_hwnd, PlatformConstants.WindowHandleType); + + var monitor = UnmanagedMethods.MonitorFromWindow( + _hwnd, + UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST); + + uint dpix, dpiy; + if (UnmanagedMethods.GetDpiForMonitor( + monitor, + UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, + out dpix, + out dpiy) == 0) + { + _scaling = dpix / 96.0; + } } private Point PointFromLParam(IntPtr lParam)