GetScaleFactorForMonitor值与应用的实际比例不匹配

时间:2015-07-10 19:26:24

标签: c# .net windows windows-8.1

我正在通过互操作调用Windows8.1 Surface3平板电脑上的GetScaleFactorForMonitor()。它的缩放系数为140.我在这款平板电脑上只有一台显示器。我将这个调用的标志设置为最接近窗口和主要显示,以查看是否有任何区别只是为了它的地狱,两者都给140.

问题是,实际缩放率为150%。当我在Windows中查看显示设置时,它显示为1440x2160,但原始分辨率为960x1440(我从调用Screen.PrimaryScreen.Bounds获得)。

调用SystemInformation.PrimaryMonitorSize.Height和Width时,我也得到960x1440。

我探索了尝试使用GetDpiForMonitor()的另一条路线。我的想法是,如果我获得原始DPI,然后是缩放的DPI,我可以进行百分比计算。

它有点奏效,但我得到的原始DPI值似乎是有效(缩放)DPI,反之亦然。对于x和y的有效DPI,我得到96,而对于原始,我得到144.我希望原始数字更低。

以下是我的电话:

GetDpiForMonitor(MonitorFromWindow(myTextbox.TopLevelControl.Handle, MONITOR_DEFAULTTONEAREST),
                                   MONITOR_DPI_TYPE.MDT_Effective_DPI,
                                   out effectiveDPIx,
                                   out effectiveDPIy);
GetDpiForMonitor(MonitorFromWindow(myTextbox.TopLevelControl.Handle, MONITOR_DEFAULTTONEAREST),
                                   MONITOR_DPI_TYPE.MDT_Raw_DPI,
                                   out rawDPIx,
                                   out rawDPIy);

这是我正在使用的结构,它是MSDN上的结构的镜像。

public enum MONITOR_DPI_TYPE : int
{
    MDT_Effective_DPI = 0,
    MDT_Angular_DPI = 1,
    MDT_Raw_DPI = 2,
    MDT_Default = MDT_Effective_DPI
};

2 个答案:

答案 0 :(得分:0)

您为Surface Pro引用的数字确实看起来不对,但是当我在我的网站上运行相同的测试时,我的原始DPI为216(这是正确的)。你确定要求RAW DPI吗?

MDT_RAW_DPI返回显示器的物理dpi - 因此不同尺寸的显示器在相同分辨率下会给出不同的答案。

例如:我的主显示器的物理宽度为23.5“,水平分辨率为3840. 3840 / 23.5 = 163 dpi

例如:surface pro 3的物理宽度为~10“,分辨率为2160. 2160/10 = 216 dpi。

这两个都与我在最新的Windows 10上运行的MDT_RAW_DPI相匹配(也许他们已经修复了什么?)

这是我的测试程序:

https://gist.github.com/toptensoftware/a6b8ca2cfc9ac63e7b6687968db408a2

答案 1 :(得分:0)

我现在意识到这已经很老了,但是值得指出为什么这似乎正在发生。

Cody Gray的评论是一个很好的起点。链接位于 https://blogs.technet.microsoft.com/askcore/2015/12/08/display-scaling-in-windows-10/标题下的“统一和扩展的缩放系统”确实表明Windows 10已统一所有API的缩放比例。

但是,https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows链接(同样来自Cody Gray)表明Windows 10对其进行了统一并不是真正的情况,至少如果您使用的是较旧的Windows版本,则不是这样。

标题“基于UI框架的每监视器DPI缩放支持”显示了例如Win32将仅为版本1703(创建者更新)返回正确的值,而如果使用Windows 1607+版本,则UWP将使用统一比例。

如果早期版本的Windows调用了GetScaleFactorForDevice(即100、140或180),则会返回相同的值。