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

 李桂平2402851397 发布于 2023-02-08 10:50

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

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

  TControl = class(TComponent)
    ...
    property Margins: TMargins read FMargins write SetMargins;

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;

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

1 个回答
  • 您可以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;
    


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

      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;
    

    仅当边距与默认值不同时,边距才会存储在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;
    

    2023-02-08 10:52 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有