Windows 11引入了一个新的选项,允许定制屏幕比例:
应用自定义缩放时,读取和写入窗体宽度和高度的行为不佳。
特别是,在我的Delphi应用程序中,每次关闭窗体时,我都会将窗体的宽度和高度存储在INI文件中,以便在下次显示窗体时恢复它们。
// store to file code
IniFile.WriteInteger('FORM','Width',AForm.Width);
IniFile.WriteInteger('FORM','Top',AForm.Top);
// restore from file code
StoredHeight:= IniFile.readInteger('FORM','Height',AForm.Height);
StoredWidth := IniFile.readInteger('FORM','Width',AForm.Width);
if StoredWidth >= Screen.Width then
AForm.Width := Screen.Width
else
begin
AForm.Width := StoredWidth;
if StoredLeft < 0 then
AForm.left := 0
else
AForm.left := StoredLeft;
end;
if StoredHeight >= Screen.Height then
AForm.Height := Screen.Height
else
begin
AForm.Height := StoredHeight;
if StoredTop < 0 then
AForm.Top := 0
else
AForm.Top := StoredTop;
end;
问题是,当TForm.Height
和TForm.Width
存储到文件中时,它们将按自定义缩放百分比(或至少增加到接近该百分比的数字)增加,而当设置这些值时,它们将被正确应用。因此,每次显示表单时,它都会变得越来越大。
我必须处理缩放问题并且必须对其进行补偿(通过将值除以缩放系数),这正常吗?我希望这对我来说是透明的。
此外,有人知道如何从Windows API中检索自定义缩放设置吗?我在谷歌上搜索了一下,但没有成功。
谢谢!
1条答案
按热度按时间ma8fv8wu1#
在Delphi 11.0 Alexandria中有一个改进。IDE现在完全支持高分辨率屏幕上的高DPI缩放。这种高DPI支持包括在代码编辑器中的支持,以及在设计窗体时VCL和FMX的支持。VCL Form Designer中有一个控制缩放的设置,因此您可以将其默认设置为未缩放。
您必须编译您的应用程序以支持高DPI(‘DPI感知’)。如果应用程序**‘不知道DPI’,Windows会将其扩展,但扩展会增加模糊性。如果应用程序是‘DPI感知’**,那么应用到其窗口的缩放就会清晰得多。
您可以将VCL Form Designer缩放到任何DPI(任何比例)。这是使用与VCL在运行时进行自我伸缩时使用的相同伸缩技术来完成的。**此设置位于工具>选项>用户界面>表单设计器>高DPI中。**更改后,需要关闭并重新打开表单设计器才能生效。
默认情况下,打开表单时,表单设计为96DPI,即100%。一个关键的知识是,当一个窗体被缩放时,Left、Height等属性都会改变。这与你运行应用程序时的情况完全相同,它会被缩放;这些值会乘以屏幕比例。
Windows(以及VCL)使用整数坐标表示其大小和位置。这意味着任何缩放可能并不总是精确的。在实践中,只需扩展一次就可以了(例如,当应用程序运行时,它从设计时的低分辨率坐标向上扩展)。它还可以进行几次微调,比如在发布后从一个显示器切换到另一个显示器。当规模扩大多次时,这一点更为重要。因此,在任何比例下以高DPI进行设计是可以的,甚至可以在较低的比例下运行-VCL将正确地缩放您的应用程序-但重要的是避免反复缩放,如果每次在设计器中打开一个表单时,它是以不同的DPI打开的,那么就会发生这种情况。
您可以在以下Embarcadero博客中阅读有关DPI扩展的更多信息:https://blogs.embarcadero.com/new-in-rad-studio-11-high-dpi-ide-and-form-designing/
首先要尝试的是禁用应用程序的每个窗体的Scaled属性(您可以在窗体的对象检查器上找到该属性),然后测试宽度和高度值是否正确写入。如果这不能解决您的问题,那么我建议您采取一些变通办法。
以下是解决方法,直到Embarcadero修复此问题。
您可以在关闭表单时保存宽度和高度值,然后根据最终用户设置的dpi对它们进行规格化(使用MulDiv函数)。
代码应该是这样的:
不过,您可以尝试使用
Monitor.PixelsPerInch
而不是Screen.PixelsPerInch
。这样,它将适用于在不同显示器上应用不同的自定义缩放比例的情况。另一个解决办法是从注册表中读取自定义缩放属性,并在规格化后保存宽度和高度值。自定义缩放属性保存在以下注册表项中:
HKEY_CURRENT_USER\Control Panel\Desktop
在LogPixels
项中。此注册表项控制Windows 10和11中的DPI缩放级别。因此,解决方法是读取此注册表项,并缩小(或放大)要写入ini文件的宽度和高度。
代码应该是这样的:
在Embarcadero解决此问题之前,我希望此解决方法将对您有所帮助。