Screen.Width报告的错误分辨率“更容易阅读屏幕上的内容”是150%

时间:2014-09-28 21:43:36

标签: delphi winapi

问题
Screen.Width / Screen.Height报告的分辨率有时(很少)小于控制面板中报告的分辨率。 Delphi报告的分辨率总是比实际分辨率小(约1/3)。它是有道理的#39;我的意思是它似乎是其中一个' round'在普通计算机中用于解析的数字,如1280x720。

我无法在我的系统中重现这一点,但我从第三方计算机获得的屏幕截图很少。

最近我用过

 var MonInfo: TMonitorInfo;
 begin
  MonInfo.cbSize := SizeOf(MonInfo);
  GetMonitorInfo(MonitorFromWindow(Application.MainForm.Handle, MONITOR_DEFAULTTONEAREST), @MonInfo);
  Result:= MonInfo.rcMonitor.Right;

它返回与Screen.Width / Screen.Height相同(错误)的结果。 这只是在几个系统上报道的(3-4)。其中两人被挂在外接显示器/电视上。

详情
德尔福显示的分辨率:1280x720
控制面板显示的分辨率:1920x1080
DPI:96
让您更容易阅读屏幕上的内容:150%
测试项目:我刚开始一个新的默认项目; ObjInspector中没有更改任何属性。用C ++编写的小型测试程序也显示错误的解决方案 德尔福XE

问题
哪个Delphi函数将返回正确的分辨率或如何根据Screen.Width(Screen.Height)报告的分辨率计算正确的分辨率?


移到这里:
How to obtain the real screen resolution in a High DPI system?

2 个答案:

答案 0 :(得分:3)

TScreen直接从Windows获取其分辨率值,因此Windows是#34;撒谎"。您的GetMonitorInfo()测试证明了这一点。我的猜测是,当您的应用遇到此问题时,可能会以兼容模式运行,特别是如果您的应用在现代Windows版本上不是High-DPI Aware。这需要您的应用使用特殊的清单值和API调用。

答案 1 :(得分:3)

您的程序并未声明自己具有高dpi感知能力。因此它受到称为DPI虚拟化的兼容模式的影响。系统将为您的程序提供假屏幕尺寸和坐标,然后将程序的显示缩放到真实尺寸。

除了为您提供您无法识别的屏幕尺寸之外,更重要的问题是DPI虚拟化会导致您的程序由于别名而显得模糊。系统会尽力扩展您的程序以适应用户所需的DPI,但是如果没有一些别名就无法缩放光栅图像。

一些有用的链接:

如果您希望避免DPI虚拟化,并让您的程序获得真正的屏幕尺寸,那么您应该将程序标记为具有高DPI感知能力。最好使用高DPI感知应用程序清单。

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" 
    xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
  <asmv3:windowsSettings 
      xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <dpiAware>true</dpiAware>
  </asmv3:windowsSettings>
  </asmv3:application>
</assembly>