GetScaleFactorForMonitor值与应用的实际比例不匹配
我在Windows8.1 Surface3平板电脑上通过interop调用GetScaleFactorForMonitor()。它以140的缩放系数进行响应。我在此平板电脑上只有一个显示器。我将这次调用的标志设置为最接近窗口和主显示,以查看它们是否有差异,并且它们都给出了140.GetScaleFactorForMonitor值与应用的实际比例不匹配
问题是,实际缩放比例是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
};
你引述的表面Pro中的数字做看上去是错误的,但是当我在我的运行同样的测试,我得到的216原始DPI(这是正确的)。你确定你要求RAW DPI吗?
MDT_RAW_DPI返回显示器的物理dpi - 因此,具有相同分辨率的不同尺寸的显示器会给出不同的答案。
例如:我的主监视器具有23.5" 的物理宽度和水平分辨率3840 3840/23.5 = 163 dpi的
例如:表面亲3具有〜10" 的物理宽度和2160的分辨率2160/10 = 216 dpi。
这两个比赛就是我从MDT_RAW_DPI得到最新上运行Windows 10的(也许他们已经固定的东西吗?)
这里是我的测试程序:
https://gist.github.com/toptensoftware/a6b8ca2cfc9ac63e7b6687968db408a2
我不知道为什么'GetScaleFactorForMonitor'没有返回正确的缩放因子。我可以重新描述你描述的确切行为。当我应用了150%的比例(测试监视器上的144 DPI,与96系统DPI相比)时,“GetScaleFactorForMonitor”返回140.显然,自144/96 = 1.5以后,它将返回150。至于你的第二个问题,我怀疑它与你的应用程序中没有包含一个清单相关,这个清单指明你的显示器与DPI兼容。请参阅:https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx –
我能想到的唯一事情就是'GetScaleFactorForMonitor'基于Windows存储缩放模式,这些模式实际上与桌面应用程序不同。 (请参阅https://blogs.technet.microsoft.com/askcore/2015/12/08/display-scaling-in-windows-10/,特别是名为“统一和扩展缩放系统”的部分。)您最好的选择是使用'GetDpiForMonitor'。即使在最新版本的Windows 10中,每个显示器扩展支持也被彻底打破了.Windows团队目前只提供了令人失望的内容。 –