11

我提出了获取用户 UI 字体偏好的调用(与 Borland 的硬编码选择“MS Sans Serif”相对)。

假设用户的字体偏好是:

Segoe Print, 15pt

我将所有应用程序中所有表单上所有项目的字体设置为:

Segoe Print, 15pt

问题是现在事情被切断了。按钮太小 - 太窄,太短。标签中的文本被切断等。

该表单具有它的 Scaled 属性,但这不会根据字体大小而改变。scaled 属性在序列化时根据数字“0”的高度对表单进行缩放。

我在帮助中找不到关于 Borland 打算如何支持用户的 Windows 应用程序首选项的任何内容。

如何处理用户字体偏好?

注意:我从 Embargadero 的新闻组服务器交叉发布了此内容,因为 Embargadero 的新闻服务器似乎正在死亡、审查、损坏或需要登录。


更新 1

我说的是用户的字体偏好,而不是 DPI 设置。即:想象以下语言中性伪代码:

procedure TForm1.FormCreate(Sender: TObject);
var
    FontFace: string;
    FontHeight: Integer;
begin
    GetUserFontPreference(out FontFace, out FontHeight);
    Self.Font.Name := FontFace;
    Self.Font.Height := FontHeight;
end;

注意:这不是我的实际代码(毕竟它是语言中性的伪代码)。但此外,您需要递归地遍历表单上的每个控件,在需要更改字体时更改字体。当字体应用了与其父字体不同的样式(例如粗体),并且不再从其父字体继承时,需要手动设置。


根据lkessler的要求,下面是从 Windows 检索用户 UI 字体首选项的代码:

procedure GetUserFontPreference(out FaceName: string; out PixelHeight: Integer);
var
    lf: LOGFONT;
begin
    ZeroMemory(@lf, SizeOf(lf));
     //Yes IconTitleFont (not SPI_GETNONCLIENTMETRICS MessageFont)
    if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(lf), @lf, 0) then
    begin
        FaceName := PChar(Addr(lf.lfFaceName[0]));
        PixelHeight := lf.lfHeight;
    end
    else
    begin
        {
            If we can't get it, then assume the same non-user preferences that
            everyone else does.
        }
        FaceName := 'MS Shell Dlg 2';
        PixelHeight := 8;
    end;
end;

相关问题

4

6 回答 6

9

首先,我们很清楚,Borland 不再拥有 Delphi。Embarcadero 现在拥有 Delphi,我们现在安全可靠。

好的,关于你的问题。

诀窍是将 TForm.AutoScroll 设置为 False 并确保您的开发机器设置为小字体。单独留下 TForm.Scaled(它的默认值为 True)。

这就是我们在内部执行此操作的方式,IDE 可以很好地处理所有内容。

于 2008-12-30T19:02:45.250 回答
3

我喜欢使用这个功能。它基于 Graphics.GetFontData

procedure SystemFont(Font: TFont);
var
  LogFont: TLogFont;
begin
  if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(TLogFont), @LogFont, 0) then
    begin
      Font.Height := LogFont.lfHeight;
      Font.Orientation := LogFont.lfOrientation;
      Font.Charset := TFontCharset(LogFont.lfCharSet);
      Font.Name := PChar(@LogFont.lfFaceName);

      Font.Style := [];

      if LogFont.lfWeight >= FW_BOLD then
        Font.Style := Font.Style + [fsBold];

      if LogFont.lfItalic = 1 then
        Font.Style := Font.Style + [fsItalic];

      if LogFont.lfUnderline = 1 then
        Font.Style := Font.Style + [fsUnderline];

      if LogFont.lfStrikeOut = 1 then
        Font.Style := Font.Style + [fsStrikeOut];

      case LogFont.lfPitchAndFamily and $F of
        VARIABLE_PITCH: Font.Pitch := fpVariable;
        FIXED_PITCH: Font.Pitch := fpFixed;
        else Font.Pitch := fpDefault;
      end;
    end;
end;

您只需在所有 TForm.OnCreate 事件上使用它。另一种方法是创建一个新类,在创建或循环 Screen.Forms 时执行此操作。

如果您更改表单上任何控件的默认字体的某些属性,它们仍将使用旧字体。如果您想要某些控件的自定义属性,则必须在调用 SystemFont 后对其进行调整。

如果表单设计器仅将更改的属性写入 .dfm 文件,则在运行时更改 Graphics.DefFontData 可能会有所帮助。

于 2009-01-15T21:43:45.570 回答
3

我和你有感觉。但平心而论:正确的 GUI 布局根本无法使用 VCL 所采用的基于像素的布局机制来创建。需要的是一个动态布局引擎,它只在之后布局控件

  1. 已为每个控件设置了正确的字体(这取决于 Windows 版本、用户偏好以及最后但并非最不重要的控件类型);和

  2. 控件中的文本已被翻译为当前语言环境,因为这可能会减少或增加控件所需的空间。

由于这完全取决于运行时属性,因此通过放置控件来创建对话框是行不通的。像 GTK 和 QT 或 wxWidgets 中的 sizer 这样的布局机制更适合。

我知道德尔福程序没有这样的事情。我在某些程序中所做的是在字体设置和文本翻译之后手动调整控件的大小和定位。很多工作,但取决于你的听众,这可能是值得的。

您还可以查看 Jordan Russell 为 Inno Setup 编写的代码。他不使用表单的 Scaled 属性,但编写了用于自定义缩放控件的代码。也许它也适用于高 DPI 屏幕上的超大字体;我注意到至少在我的 124 DPI 笔记本电脑屏幕上,设置对话框看起来相当不错。

于 2008-12-30T20:24:06.257 回答
2

To do this right, I think you would have to:

1 - Load the user's font preference

2 - Apply it as you've described

3 - Determine the width and height of all captions (in pixels) and compare that to the control's width & height, and adjust accordingly.

Unfortunately, the "adjust accordingly" part is hard. You could widen a button, but then you'd have to check whether that is overlapping with another control.

Your best bet might be to create slightly oversized controls, and hope the user doesn't choose a 32-point font size.

于 2008-12-30T21:03:36.253 回答
1

Kogus had the right idea, but left out the function you need to use. It would be the Windows GetTextExtentPoint32 routine. You pass it a string and it calculates the width and height of the string using the currently selected font. You'll find it in Windows.pas.

You might want to calculate in advance what the maximum space you would need for fonts you allow.

Or you might use the function to dynamically adjust the size of the area displaying the text so that it fits.

This would be fine for one or two controls, but either method would be a lot of work if you're trying to do this on your whole user interface.

于 2008-12-30T23:59:14.997 回答
0

我会说这类似于翻译。在我们的应用程序中,我们将按钮、标签、编辑等所有内容都做得更大一点,以便可以轻松容纳某些语言所需的较长单词。它不会对设计造成一点伤害。

于 2008-12-31T10:13:25.303 回答