Browse Source

Merge pull request #3124 from AvaloniaUI/fix-win7-dpi-error

Fallback to GDI when ShCore.dll isnt found (win7/8).
pull/3131/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
d9ffc6c0e0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  2. 26
      src/Windows/Avalonia.Win32/ScreenImpl.cs

9
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -1031,6 +1031,9 @@ namespace Avalonia.Win32.Interop
[DllImport("shcore.dll")]
public static extern long GetDpiForMonitor(IntPtr hmonitor, MONITOR_DPI_TYPE dpiType, out uint dpiX, out uint dpiY);
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hdc, DEVICECAP nIndex);
[DllImport("shcore.dll")]
public static extern void GetScaleFactorForMonitor(IntPtr hMon, out uint pScale);
@ -1147,6 +1150,12 @@ namespace Avalonia.Win32.Interop
}
}
public enum DEVICECAP
{
HORZRES = 8,
DESKTOPHORZRES = 118
}
public enum PROCESS_DPI_AWARENESS
{
PROCESS_DPI_UNAWARE = 0,

26
src/Windows/Avalonia.Win32/ScreenImpl.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods;
namespace Avalonia.Win32
@ -28,9 +29,28 @@ namespace Avalonia.Win32
(IntPtr monitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr data) =>
{
MONITORINFO monitorInfo = MONITORINFO.Create();
if (GetMonitorInfo(monitor,ref monitorInfo))
if (GetMonitorInfo(monitor, ref monitorInfo))
{
GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var x, out _);
var dpi = 1.0;
var shcore = LoadLibrary("shcore.dll");
var method = GetProcAddress(shcore, nameof(GetDpiForMonitor));
if (method != IntPtr.Zero)
{
GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var x, out _);
dpi = (double)x;
}
else
{
var hdc = GetDC(IntPtr.Zero);
double virtW = GetDeviceCaps(hdc, DEVICECAP.HORZRES);
double physW = GetDeviceCaps(hdc, DEVICECAP.DESKTOPHORZRES);
dpi = (96d * physW / virtW);
ReleaseDC(IntPtr.Zero, hdc);
}
RECT bounds = monitorInfo.rcMonitor;
RECT workingArea = monitorInfo.rcWork;
@ -40,7 +60,7 @@ namespace Avalonia.Win32
new PixelRect(workingArea.left, workingArea.top, workingArea.right - workingArea.left,
workingArea.bottom - workingArea.top);
screens[index] =
new WinScreen((double)x / 96.0d, avaloniaBounds, avaloniaWorkArea, monitorInfo.dwFlags == 1,
new WinScreen(dpi / 96.0d, avaloniaBounds, avaloniaWorkArea, monitorInfo.dwFlags == 1,
monitor);
index++;
}

Loading…
Cancel
Save