【发布时间】:2020-03-17 04:38:45
【问题描述】:
微软不知道如何帮助我,所以我不得不在这里问。
我有三台显示器...
- 屏幕 1:3840 x 2160,缩放 150%
- 屏幕 2:1920 x 1200,缩放 100%
- 屏幕 3:1920 x 1200,缩放 100%
我需要在VB.net 或C# 中获取每个监视器的缩放比例。
Microsoft 建议我使用此代码:
Private Declare Function GetDeviceCaps Lib "gdi32.dll" (hdc As IntPtr, nIndex As Integer) As Integer
Public Enum DeviceCap
VERTRES = 10
DESKTOPVERTRES = 117
End Enum
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
For Each screen As Forms.Screen In Forms.Screen.AllScreens
Dim pnt = New System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1)
Dim mon = MonitorFromPoint(pnt, 2)
Dim fac As Single = GetScalingFactor(mon)
Console.WriteLine($"Factor: {fac}")
Next
End Sub
Private Function GetScalingFactor(monitorHandle As IntPtr) As Single
Dim g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
Dim desktop As IntPtr = g.GetHdc()
Dim LogicalScreenHeight As Integer = GetDeviceCaps(desktop, CInt(DeviceCap.VERTRES))
Dim PhysicalScreenHeight As Integer = GetDeviceCaps(desktop, CInt(DeviceCap.DESKTOPVERTRES))
Dim ScreenScalingFactor As Single = CSng(PhysicalScreenHeight) / CSng(LogicalScreenHeight)
Return ScreenScalingFactor
End Function
但它为我的所有屏幕返回 1 的比例。
我需要它独立于我的应用是否支持 dpiAware,因此我必须以某种方式从屏幕控制面板读取它。
该解决方案必须适用于 Windows 10 和 Windows Server 2012 R2 远程桌面客户端。
【问题讨论】:
-
This 解决方案对我来说效果很好。
-
@JoãoSilva - 我的注册表中没有 LogPixels 条目。不过还是谢谢。
-
This 似乎以各种方式做到了这一点(尽管在 C# 中,但应该很容易转换)。选择您的选择。
-
@Christian.K ...是的,这也是微软的建议之一,但正如许多 cmets 所说,GetDeviceCaps 总是返回 1 ...所以我们不得不放弃它。
-
您的代码使用 WPF 样式的事件处理程序。这是一个 WPF 应用程序吗? WPF 应用程序 本质上 是 DpiAware,除非您强制禁用它。为什么不使用
PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice;返回的矩阵呢?在 WPF 中使用Graphics.FromHwnd()没有任何意义。