Delphi TFontDialog - 如何适配高 DPI?

7
我希望在高分辨率显示器上使用Delphi 10.3.3中的TFontDialog,但遗憾的是Delphi并没有真正缩放内容。(请查看示例(Beispiel)的位置!) 我有2个显示器。主要的显示器有96ppi,另一个显示器有144ppi。我的应用运行在第二个显示器上。你在你的应用程序中如何解决这样的问题?有没有办法解决这个问题,还是我必须希望Delphi 10.4会解决这个问题?200%及以上的显示倍数已经无法读取字体大小了。

2
您应该启用应用程序的 DPI 意识。如果您需要具有不同 DPI 值的多监视器 UI,请使用“每个监视器”意识。以下是一个在 Windows 平台上获取有关此信息的链接:https://learn.microsoft.com/zh-cn/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows - The Bitman
问题是在调试模式或exe运行时也出现吗?如果只在前一种情况下,则在Delphi RAD Studio的启动图标上设置DPI感知。 (右键单击,属性,兼容性,更改高DPI设置) - The Bitman
3
TFontDialog只是Win32 ChooseFont() API的一个包装器,因此对话框中的任何 DPI 问题都取决于操作系统本身,而不是VCL。 - Remy Lebeau
1
@Jens 当使用FontDialog.Execute打开对话框时,您是否像这样将您的表单窗口句柄作为参数传递给执行调用FontDialog1.Execute(Form1.Handle)?不确定,但我猜测这是必需的,以便对话框可以检索打开的显示器的正确DPI分辨率。 - SilverWarior
1
如果在Execute()中没有传递HWND,则它将使用当前活动窗体的HWND。 - Remy Lebeau
显示剩余7条评论
1个回答

1

很遗憾,TFontDialog,或者准确地说是来自Windows的底层ChooseFont,目前还不支持逐个监视器 V2 DPI感知。作为解决方法,您可以在显示对话框时暂时切换到系统感知,然后再切换回来。

为了实现这一点,我建议使用一个中间类来覆盖TFontDialog

type
  TFontDialog = class(Vcl.Dialogs.TFontDialog)
  protected
    function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; override;
  end;

function TFontDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
var
  previousDpiContext: DPI_AWARENESS_CONTEXT;
begin
  previousDpiContext := SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
  try
    Result := inherited TaskModalDialog(DialogFunc, DialogData);
  finally
    SetThreadDpiAwarenessContext(previousDpiContext);
  end;
end;

请注意,对话框中给定和检索到的字体大小是基于系统 DPI 的,必须从/到使用的监视器 DPI 进行缩放。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接