Delphi:处理用户的字体首选项

时间:2008-12-30 18:40:32

标签: delphi preferences dpi

我想出了获取用户UI字体首选项的调用(如 反对Borland对“MS Sans Serif”的硬编码选择。

让我们假装用户的字体偏好是:

Segoe Print, 15pt

我将所有表格中所有项目的字体设置为:

Segoe Print, 15pt

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

表单具有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;

相关问题

6 个答案:

答案 0 :(得分:9)

首先,我们很清楚,Borland不再拥有Delphi了。 Embarcadero现在拥有德尔福,现在我们安全,安全。

好的,关于你的问题。

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

这就是我们在这里内部执行的方式,IDE处理的一切都很好。

答案 1 :(得分:3)

我和你在一起。但公平地说:使用VCL采用的基于像素的布局机制无法创建正确的GUI布局。我们需要的是一个动态布局引擎,它只在

之后布局控件
  1. 为每个控件设置了正确的字体(这取决于Windows版本,用户首选项,以及最后但并非最不重要的控件类型);以及

  2. 控件中的文本已转换为当前区域设置,因为这可能会减少或增加控件所需的空间。

  3. 由于这完全取决于运行时属性,因此通过放置控件创建对话框无法正常工作。像GTK和QT那样的布局机制或wxWidgets中的sizer更适合。

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

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

答案 2 :(得分: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可能会有所帮助。

答案 3 :(得分:2)

要做到这一点,我认为你必须:

1 - 加载用户的字体首选项

2 - 按照你的描述应用它

3 - 确定所有字幕的宽度和高度(以像素为单位),并将其与控件的宽度和宽度进行比较。高度,并相应调整。

不幸的是,“相应调整”部分很难。你可以加宽按钮,但是你必须检查它是否与另一个控件重叠。

您最好的选择可能是创建略微超大的控件,并希望用户不要选择32磅的字体大小。

答案 4 :(得分:1)

Kogus有正确的想法,但遗漏了你需要使用的功能。这将是Windows GetTextExtentPoint32例程。您传递一个字符串,它使用当前选定的字体计算字符串的宽度和高度。你可以在Windows.pas。

中找到它

您可能需要提前计算您允许的字体所需的最大空间。

或者您可以使用该功能动态调整显示文本区域的大小,使其适合。

对于一个或两个控件来说这没什么问题,但如果您尝试在整个用户界面上执行此操作,则任何一种方法都会有很多工作。

答案 5 :(得分:0)

我说这与翻译类似。在我们的应用程序中,我们制作了按钮,标签,编辑,一些更大的内容,以便可以轻松容纳某些语言所需的更长的单词。它不会对设计造成任何影响。