Browse Source

Use actual DPI for scaling factor.

Doesn't change when DPI changes yet though.
pull/447/head
Steven Kirk 10 years ago
parent
commit
e742237d00
  1. 20
      src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs
  2. 26
      src/Windows/Perspex.Win32/Win32Platform.cs
  3. 23
      src/Windows/Perspex.Win32/WindowImpl.cs

20
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); public static extern void GetScaleFactorForMonitor(IntPtr hMon, out uint pScale);
[DllImport("user32.dll")] [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; [DllImport("user32.dll")]
public const uint MONITOR_DEFAULTTOPRIMARY = 0x00000001; public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags);
public const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
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_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2 PROCESS_PER_MONITOR_DPI_AWARE = 2
} }
public enum MONITOR_DPI_TYPE { public enum MONITOR_DPI_TYPE
{
MDT_EFFECTIVE_DPI = 0, MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1, MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2, MDT_RAW_DPI = 2,

26
src/Windows/Perspex.Win32/Win32Platform.cs

@ -22,16 +22,15 @@ namespace Perspex.Win32
{ {
private static readonly Win32Platform s_instance = new Win32Platform(); private static readonly Win32Platform s_instance = new Win32Platform();
private static Thread _uiThread; private static Thread _uiThread;
private UnmanagedMethods.WndProc _wndProcDelegate; private UnmanagedMethods.WndProc _wndProcDelegate;
private IntPtr _hwnd; private IntPtr _hwnd;
private double _scale = 1.0;
private readonly List<Delegate> _delegates = new List<Delegate>(); private readonly List<Delegate> _delegates = new List<Delegate>();
public Win32Platform() 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(); CreateMessageWindow();
} }
@ -40,8 +39,6 @@ namespace Perspex.Win32
UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDOUBLECLK)); UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDOUBLECLK));
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(UnmanagedMethods.GetDoubleClickTime()); public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(UnmanagedMethods.GetDoubleClickTime());
public double RenderScalingFactor => _scale;
public double LayoutScalingFactor => _scale;
public static void Initialize() public static void Initialize()
{ {
@ -173,22 +170,5 @@ namespace Perspex.Win32
{ {
return new PopupImpl(); 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;
}
} }
} }

23
src/Windows/Perspex.Win32/WindowImpl.cs

@ -26,18 +26,13 @@ namespace Perspex.Win32
IntPtr.Zero, new IntPtr((int)UnmanagedMethods.Cursor.IDC_ARROW)); IntPtr.Zero, new IntPtr((int)UnmanagedMethods.Cursor.IDC_ARROW));
private UnmanagedMethods.WndProc _wndProcDelegate; private UnmanagedMethods.WndProc _wndProcDelegate;
private string _className; private string _className;
private IntPtr _hwnd; private IntPtr _hwnd;
private IInputRoot _owner; private IInputRoot _owner;
private bool _trackingMouse; private bool _trackingMouse;
private bool _isActive; private bool _isActive;
private bool _decorated = true; private bool _decorated = true;
private double _scaling = 1;
public WindowImpl() public WindowImpl()
{ {
@ -103,7 +98,7 @@ namespace Perspex.Win32
} }
} }
public double Scaling => 1; public double Scaling => _scaling;
public IPlatformHandle Handle public IPlatformHandle Handle
{ {
@ -562,6 +557,20 @@ namespace Perspex.Win32
} }
Handle = new PlatformHandle(_hwnd, PlatformConstants.WindowHandleType); 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) private Point PointFromLParam(IntPtr lParam)

Loading…
Cancel
Save