项目中的字体一致性?

时间:2012-05-14 18:03:56

标签: delphi delphi-xe

是否有一种快速有效的方法来应用项目中使用的全局字体?

我的意思是我想设置一个特定的字体名称,我项目中的所有控件都会使用这些名称,例如TButtonTEditTLabel等。

通常为表单而不是特定控件设置字体会将该表单上的所有控件更改为指定的字体。

但是,如果您在特定控件上手动更改了字体,那么通过表单设置字体将不再更新先前已手动更改的控件。

创意1

我正在考虑使用For循环并迭代我的Forms上的每个组件并以这种方式设置Font,例如:

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  with TForm(Self) do
  begin
    for i := 0 to ComponentCount - 1 do
    begin
      if Components[i] is TButton then
      begin
        TButton(Components[i]).Font.Name  := 'MS Sans Serif';
        TButton(Components[i]).Font.Size  := 8;
        TButton(Components[i]).Font.Style := [fsBold];
      end;

      if Components[i] is TLabel then
      begin
        TLabel(Components[i]).Font.Name  := 'MS Sans Serif';
        TLabel(Components[i]).Font.Size  := 8;
        TLabel(Components[i]).Font.Style := [fsBold];
      end;
    end;
  end;
end;

但这样做看起来非常混乱,对于一项简单的任务来说,这也是相当多的代码。

创意2

我知道我可以在设计时手动为每个控件逐个手动更改字体,但有几种形式需要时间,即使这样我也可能错过了控件。

创意3

与Idea 2类似,另一种方法是将表单视为文本(DFM)并查找和替换该字体。


基本上我要在我的应用程序中保持一致性,并且在整个过程中使用一个Font就是我想要实现的目标。

我是否遗漏了一些在这里完全显而易见的东西,我正在努力为这样的任务做些什么?

3 个答案:

答案 0 :(得分:24)

正如评论中所讨论的,关键是ParentFont属性。此属性在VCL层次结构中的各个点定义。如果您为链中的所有组件设置ParentFontTrue,则只需修改

即可更改整个应用程序的字体
Application.DefaultFont

默认情况下,大多数组件会将ParentFont设置为True,因此您无需执行任何操作。奇怪的是TForm。全新的默认表单ParentFont设置为False。这有点令人失望,但我怀疑VCL的原始设计师没有预料到这一点,并且ParentFont在VCL开发的相对较晚时被嫁接。

无论如何,在理想的世界中,应用程序中的所有表单都应该来自您控制的公共基类。如果是这样,那么您只需在那里进行更改,将ParentFont设置为True,确保没有明确的字体设置应用于您表单上的任何组件,并且您是金色的。通过单个属性控制整个应用程序的字体。如果您没有表单的公共基类,这是添加表单的理想时间。如果您不想这样做,则需要为每个表单设置ParentFont

其他相关属性为Screen.MessageFontScreen.MenuFont。它们提供对消息框和菜单中使用的字体的全局控制。但是,最新版本的Delphi已经回复了Windows对消息框和菜单绘制的控制,因此这些属性没有任何效果。

答案 1 :(得分:2)

如上所述,真正的关键是确保所有表单都来自您自己的应用程序基础表单。

然后,您可以查看每个表单和按钮等,并查看属性,其中任何已修改的字体属性应以粗体显示,并且很容易识别。大多数属性都有“恢复为继承”菜单选项。这基本上应该撤消任何先前的选择,而不必转到文本版本进行编辑。 (虽然它可能正是如此,但删除了之前字体设置产生的任何文本条目。)

我肯定想要修复每个表单一次而不是错误地定义并添加更多代码以在运行时修复它。如果你后来决定采取不同的做法,这种改变会给你带来更糟糕的问题。

答案 2 :(得分:1)

如果你想做这个运行时,就像你在Idea 1中描述的那样,你应该考虑使它成为一个递归函数,如下所示:

procedure SetFontProperties(Control: TControl; Name: TFontName; Size: Integer; Styles: TFontStyles);
// Set font properties
var
  Index: Integer;
  Font: TFont;
  AnObject: TObject;
  ChildControl: TControl;
begin
  // Set font properties
  AnObject := GetObjectProp(Control, 'Font', nil);
  if AnObject is TFont then
  begin
    // Set properties
    Font := TFont(AnObject);
    Font.Name  := Name;
    Font.Size  := Size;
    Font.Style := Styles;
  end;

  // Set child font properties
  if Control is TWinControl then
  begin
    // Set
    for Index := 0 to TWinControl(Control).ControlCount - 1 do
    begin
      // Child control
      ChildControl := TWinControl(Control).Controls[Index];

      // Set font properties
      SetFontProperties(ChildControl, Name, Size, Styles);
    end;
  end;
end;

然后,您可以像这样使用它来切换表单中所有控件的字体:

SetFontProperties(Self, 'Courier', 14, []);

然后,该函数将设置表单的字体属性以及表单上所有子控件的字体属性,包括嵌套在TPanels或其他容器控件中的控件。

但是我同意你的观点,这是一种半混乱的方式。