Delphi 屏幕报告的分辨率错误。宽度为“时”;使阅读内容更容易';“屏幕上的s”;是150%

Delphi 屏幕报告的分辨率错误。宽度为“时”;使阅读内容更容易';“屏幕上的s”;是150%,delphi,winapi,Delphi,Winapi,问题 Screen.Width/Screen.Height报告的分辨率有时(很少)小于控制面板中报告的分辨率。Delphi报告的分辨率总是比实际分辨率小(约1/3)。这是“有道理的”。我的意思是,它似乎是普通计算机中用于分辨率的“四舍五入”数字之一,比如1280x720 我无法在我的系统中复制这一点,但我从第三方计算机上获得了一些屏幕截图 最近我用 var MonInfo: TMonitorInfo; begin MonInfo.cbSize := SizeOf(MonInfo);

问题
Screen.Width/Screen.Height报告的分辨率有时(很少)小于控制面板中报告的分辨率。Delphi报告的分辨率总是比实际分辨率小(约1/3)。这是“有道理的”。我的意思是,它似乎是普通计算机中用于分辨率的“四舍五入”数字之一,比如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)上报告了这一点。其中两个连接到外部监视器/电视

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

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


搬到这里:

TScreen
直接从Windows获取分辨率值,因此Windows才是“说谎的”。您的
GetMonitorInfo()
测试证明了这一点。我的猜测是,当您的应用程序出现此问题时,它可能是在兼容模式下运行的,尤其是当您的应用程序不在现代Windows版本上时。这要求你的应用程序使用特殊的清单值和API调用。

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

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

一些有用的链接:

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


真的

我的应用程序是用Delphi XE创建的。我启动了一个新项目,只在其中添加了Screen.Width/Screen.Height和GetMonitorInfo函数。@remy-我确认用户的DPI设置为96,但“使屏幕上的内容更易于阅读”设置为“更大的150%”AFAIK,“150%”对应于120 DPI。如果您获得96,则需要DPI虚拟化。请尝试致电SetProcessDPIAware。谢谢David。我将尝试清单并返回结果。我看到人们建议不要让您的DPI知晓()。所以,我想要一个“脏”的解决方案,其中我只得到真正的屏幕分辨率。有什么方法可以计算出来吗?你可以创建一个支持DPI的小程序,然后启动新的程序来获取信息。或者您也可以使用WMI查询来执行此操作。我看不出有任何理由不了解高DPI。我能想象这样做的唯一原因是如果你想让你的程序变得糟糕。在没有高DPI感知的现代屏幕上,它看起来会令人震惊。WarenP在这里发出了一个关于切换到DPI感知的警告:我的应用程序运行的是高DPI感知,可扩展到至少200%。你不能永远忽视这一点。现代高像素密度笔记本电脑无法100%缩放,因为文本太小。不管你喜欢与否,高DPI即将到来。若你们让Windows用光栅缩放的方式来缩放你们的应用程序,那个么你们的应用程序将会非常糟糕。