Tôi đã tìm được cách để lấy dpi bằng WinAPI. Lần đầu tiên cần tham chiếu đến System.Drawing
và System.Windows.Forms
. Có thể nhận được màn hình xử lý với WinAPI từ một điểm trên vùng hiển thị - lớp Screen
có thể cho chúng ta điểm này. Sau đó, chức năng GetDpiForMonitor
trả về dpi của màn hình được chỉ định.
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,
}
Có ba loại tỷ lệ, bạn có thể tìm thấy description in the MSDN.
Tôi đã thử nghiệm nó một cách nhanh chóng với một ứng dụng WPF mới:
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;
}
}
Tôi hy vọng nó sẽ giúp!
Bạn có thể tạo cửa sổ giả trên mỗi màn hình và lấy thông tin theo cách này không? –
Bạn có thể đi với nhận xét trước đó, nếu không bạn sẽ phải liệt kê các thiết bị hiển thị và nhận DPI theo cách đó. – Kcvin
Windows hiện hỗ trợ DPI trên mỗi màn hình, bắt đầu bằng 8,1. Bạn có thể gặp phải nó trong một thiết lập, nơi bạn có một màn hình "võng mạc" đắt tiền và một màn hình khác, thường là một máy chiếu. Backgrounder cho WPF [ở đây] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee308410%28v=vs.85%29.aspx). –