Using the Delphi XE2 wizard to create a component, I have choose the TPanel to inherit from, and change defaults of some properties to fit my application.
My problem is to change the default of Margins:
TControl = class(TComponent)
...
property Margins: TMargins read FMargins write SetMargins;
Margins is a TMargin class declared with 4 properties that I need to redefine the defaults:
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;
I can/will be setting on code the margins when the constructor of the component is called, however I have no idea how to redefine these defaults above in order to show up on the property editor.
The CSS styles it. To give your paragraph a margin, you would write it in your styles. css file as: p { margin: 16px; }; or p { margin: 5px; }. Remember, cascading style sheets means that if the first margin is 16px, then you change the margin later to 5px, the latter margin overrides the previous margin.
By default, the left and right margins of a text element are set to 0 , but they all come with a margin-top and margin-bottom .
Adjusting the Margin Size of an HTML Element With CSS You can remove this margin by setting the top and left margin to zero. Like the padding and border, the sizes of specific sides of the margin can be set using margin-left , margin-right , margin-top , and margin-bottom .
You can declare your TMargins
descendant with your own defaults to use in your panel
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;
then when you create your panel, dismiss the existing one and use yours
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;
The margins will be stored in the dfm only when they differ from the default.
Although I don't know why the above works... The problem with the above code is, Margins
property have a setter which only assigns to the margins (left, right..). The code never writes to the backing field, but it still works. The line
Margins := TMyMargins.Create(Self);
is effectively same as
TMyMargins.Create(Self);
which also works.
By 'works' I mean, it works. The margins, f.i., gets properly destroyed, not because of ownership etc.. (margins iş a TPersistent
, not a component) but right when the ascendant TControl
calls FMargins.Free
.
Anyway, since I don't understand how it works, as a safer although hacky approach, I'd use this:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With