Browse Source

Use actual DPI for scaling factor.

Doesn't change when DPI changes yet though.
Steven Kirk 9 years ago
parent
commit
e742237d00

+ 14 - 6
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,

+ 3 - 23
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<Delegate> _delegates = new List<Delegate>();
 
         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;
-        }
     }
 }

+ 16 - 7
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)