Znalazłem sposób na uzyskanie rozdzielczości za pomocą interfejsu WinAPI. Jako pierwsza potrzebuje referencji do System.Drawing
i System.Windows.Forms
. Możliwe jest uzyskanie uchwytu monitora za pomocą interfejsu WinAPI z punktu na obszarze wyświetlania - klasa Screen
może dać nam te punkty. Następnie funkcja GetDpiForMonitor
zwraca wartość dpi określonego monitora.
public static class ScreenExtensions
{
public static void GetDpi(this System.Windows.Forms.Screen screen, DpiType dpiType, out uint dpiX, out uint dpiY)
{
var pnt = new System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1);
var mon = MonitorFromPoint(pnt, 2/*MONITOR_DEFAULTTONEAREST*/);
GetDpiForMonitor(mon, dpiType, out dpiX, out dpiY);
}
//https://msdn.microsoft.com/en-us/library/windows/desktop/dd145062(v=vs.85).aspx
[DllImport("User32.dll")]
private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);
//https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
[DllImport("Shcore.dll")]
private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);
}
//https://msdn.microsoft.com/en-us/library/windows/desktop/dn280511(v=vs.85).aspx
public enum DpiType
{
Effective = 0,
Angular = 1,
Raw = 2,
}
Istnieją trzy rodzaje skalowania, można znaleźć description in the MSDN.
Testowałem go szybko z nowej aplikacji WPF:
private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var sb = new StringBuilder();
sb.Append("Angular\n");
sb.Append(string.Join("\n", Display(DpiType.Angular)));
sb.Append("\nEffective\n");
sb.Append(string.Join("\n", Display(DpiType.Effective)));
sb.Append("\nRaw\n");
sb.Append(string.Join("\n", Display(DpiType.Raw)));
this.Content = new TextBox() { Text = sb.ToString() };
}
private IEnumerable<string> Display(DpiType type)
{
foreach (var screen in System.Windows.Forms.Screen.AllScreens)
{
uint x, y;
screen.GetDpi(type, out x, out y);
yield return screen.DeviceName + " - dpiX=" + x + ", dpiY=" + y;
}
}
Mam nadzieję, że to pomaga!
Czy możesz po prostu utworzyć fałszywe okno na każdym ekranie i pobrać informacje w ten sposób? –
Możesz przejść do poprzedniego komentarza, w przeciwnym razie będziesz musiał wyliczyć urządzenia wyświetlające i uzyskać DPI w ten sposób. – Kcvin
System Windows obsługuje teraz DPI dla poszczególnych ekranów, począwszy od wersji 8.1. Najprawdopodobniej natkniesz się na to w konfiguracji, w której masz jeden kosztowny wyświetlacz "siatkówkowy" i inny prosty, zwykle projektor. Wersja dla WPF [jest tutaj] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee308410%28v=vs.85%29.aspx). –