如何更改Margins属性的默认值?

Edu*_*ias 7 delphi components delphi-xe2

使用Delphi XE2向导创建组件,我选择要继承的TPanel,并更改某些属性的默认值以适合我的应用程序.

我的问题是更改边距的默认值:

  TControl = class(TComponent)
    ...
    property Margins: TMargins read FMargins write SetMargins;
Run Code Online (Sandbox Code Playgroud)

Margins是一个TMargin类,使用4个属性声明,我需要重新定义默认值:

  TMargins = class(TPersistent)
  published
    property Left: TMarginSize index 0 read FLeft write SetMargin default 3;
    property Top: TMarginSize index 1 read FTop write SetMargin default 3;
    property Right: TMarginSize index 2 read FRight write SetMargin default 3;
    property Bottom: TMarginSize index 3 read FBottom write SetMargin default 3;
Run Code Online (Sandbox Code Playgroud)

我可以/将在调用组件的构造函数时将代码设置为边距,但是我不知道如何重新定义上面的这些默认值以便显示在属性编辑器上.

Ser*_*yuz 7

您可以TMargins使用自己的默认值声明您的后代,以在面板中使用

type
  TMyMargins = class(TMargins)
  protected
    class procedure InitDefaults(Margins: TMargins); override;
  published
    property Left default 10;
    property Top default 10;
    property Right default 10;
    property Bottom default 10;
  end;

class procedure TMyMargins.InitDefaults(Margins: TMargins);
begin
  with Margins do begin
    Left := 10;
    Right := 10;
    Top := 10;
    Bottom := 10;
  end;
end;
Run Code Online (Sandbox Code Playgroud)


然后在创建面板时,关闭现有面板并使用您的面板

  TMyPanel = class(TPanel)
  private
    procedure DoMarginChange(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Margins.Free;
  Margins := TMyMargins.Create(Self);
  Margins.OnChange := DoMarginChange;
end;

procedure TMyPanel.DoMarginChange(Sender: TObject);
begin
  // same as in TControl which is private
  RequestAlign;
end;
Run Code Online (Sandbox Code Playgroud)

仅当边距与默认值不同时,边距才会存储在dfm中.



虽然我不知道为什么上面的工作...上面的代码的问题是,Margins属性有一个setter只分配到边距(左,右..).代码永远不会写入支持字段,但它仍然有效.这条线

Margins := TMyMargins.Create(Self);

实际上是一样的

TMyMargins.Create(Self);

这也有效.

我的意思是'作品',它有效.边缘,fi,被正确销毁,而不是因为所有权等...(边缘işa TPersistent,而不是组件),但正好上升时TControl调用FMargins.Free.

无论如何,因为我不明白它是如何工作的,作为一个更安全但更糟糕的方法,我会用它:

constructor TMyPanel.Create(AOwner: TComponent);
var
  Addr: NativeUInt;
begin
  inherited Create(AOwner);

  Addr := NativeUInt(@Margins);
  Margins.Free;
  PUINT_PTR(Addr)^ := NativeUInt(TMyMargins.Create(Self));
  Margins.OnChange := DoMarginChange;
end;
Run Code Online (Sandbox Code Playgroud)