如何使TFont属性在对象检查器中显示为默认值?

4

概述

在编写组件时,我喜欢给我的发布属性一个默认值,这样对象检查器就会以加粗的方式显示所有新更改的属性。这对于使用组件的人来说非常有用,因为他们可以轻松地识别默认和修改后的值。

例子

这是一个包含两个颜色和两个字体属性的组件示例:

我正在将发布属性 default 写入类结构中:

type
  TMyComponent = class(TComponent)
  private
    FColor: TColor;
    FColorTo: TColor;
    FFont: TFont;
    FFontHot: TFont;
    procedure SetColor(const Value: TColor);
    procedure SetColorTo(const Value: TColor);
    procedure SetFont(const Value: TFont);
    procedure SetFontHot(const Value: TFont);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Color: TColor read FColor write SetColor default clGreen;
    property ColorTo: TColor read FColorTo write SetColorTo default clBlue;
    property Font: TFont read FFont write SetFont; //< set default?
    property FontHot: TFont read FFontHot write SetFontHot; //< set default?
  end;

以及构造函数:

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FColor := clGreen;
  FColorTo := clBlue;

  FFont := TFont.Create;
  FFont.Color := clRed;
  FFont.Name := 'Segoe UI';
  FFont.Size := 10;
  FFont.Style := [];

  FFontHot:= TFont.Create;
  FFontHot.Color := clNavy;
  FFontHot.Name := 'Verdana';
  FFontHot.Size := 8;
  FFontHot.Style := [fsItalic];
end;

destructor TMyComponent.Destroy;
begin
  FFont.Free;
  FFontHot.Free;

  inherited Destroy;
end;

问题

我的问题是如何将已发布的字体属性“标记”为默认值?

当我将组件添加到表单中时,对象检查器中的两个TFont属性都是粗体(非默认)。如果我单击每个已发布字体旁边的省略号,我可以看到从构造函数设置的值显示出来 - 但它们仍然是粗体。然而,奇怪的是,每个字体的大小值从未以粗体显示(即未更改)。

标准已发布属性可以非常容易地设置为default,但是如何处理具有子属性的TFont等类呢?

我无法从类结构中设置默认值,只能在构造函数中设置。即使我能够从类结构中定义默认值(这似乎是不可能的),我也怀疑它是否有效,因为字体尚未创建。例如(显然不起作用):

published
  property FontHot: TFont read FFontHot write SetFontHot default FFontHot.Color := clRed; //< set default?

那么,当我将新组件添加到对象检查器时,如何使已发布的TFont属性显示为默认值且不变?我猜其他类似于TFont的具有子属性的类也适用。
1个回答

10

对于对象属性,默认的存储说明符(storage specifier)stored。在stored后面,可以是False(从不保存到DFM),True(总是保存)或返回其中之一的无参数函数。你需要最后一种情况:

private
  function IsFontStored: Boolean;
published
  property Font: TFont read FFont write SetFont stored IsFontStored;

IsFontStored 函数中,您可以判断当前设置的字体是否为 默认字体。如果是,请返回 False


太棒了,我从来不知道这个神奇的词。我发誓 Delphi 帮助文档从未帮助我找到我需要的东西。 - user1175743
不需要帮助,在这种情况下,我会深入研究VCL代码,探索它是如何完成的。 - NGLN
是的,我想是这样的。但通常情况下,我不知道我在寻找什么或从哪里开始——特别是当学习新事物时,比如存储说明符,如果没有你回答问题,我甚至都不会意识到它的存在 :) - user1175743
我完全理解,实际上:VCL代码并没有解释它是如何工作的,也没有说明它的名称。但是我想说的是,通过普通程序员的好奇心,随意单击字体属性中的任意一个,最终会导致其声明。然后,一旦找到存储的指令,您就有了要搜索的关键字。更多好奇心将导致在存储指令之后单击标识符,一个全新的世界将展现在您面前....;-) - NGLN
不错的观点,尽管Ctrl+单击并不总是有效。我应该尝试更深入地了解底层的Delphi代码,即使我会在其中迷失方向,这与尝试使用帮助文件并不清晰的情况没有什么区别。毋庸置疑,几乎每天使用Delphi,我都会通过像你这样的答案或自己的发现学到新东西。 - user1175743

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