For some time now I have been struggling with the strage behavior of controls with Align
or Anchors
settings (like here). This time I worked with one unit until I noticed that the top position of the buttons moved from the original 10 to something about -50, so I tried to find out what was the cause.
If I use panel with BevelKind = bkFlat
and controls with Anchors = [akRight, akBottom]
then the position of all controls will be reduced according to the settings. As shown in the following example, Left
moves with Anchors = [akRight]
and Top
with Anchors = [akBottom]
. Always in the width of the bevels that the panel has set, in this case -4 in both directions. After running the program or reopening the following unit, position moves from (150, 10)
to (146, 6)
and will continue indefinitely after opening and saving the unit.
So I'd like to know what is responsible for position recalculation of all components after opening the unit and saving into dfm
file, if it is possible to fix it.
PMain.pas
unit PMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Grids;
type
TUMain = class(TForm)
pnl1: TPanel;
btn1: TButton;
end;
var
UMain: TUMain;
implementation
{$R *.dfm}
end.
PMain.dfm
object UMain: TUMain
Left = 0
Top = 0
Caption = 'UMain'
ClientHeight = 50
ClientWidth = 250
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object pnl1: TPanel
Left = 0
Top = 0
Width = 250
Height = 50
Align = alClient
BevelKind = bkFlat
Caption = 'pnl1'
TabOrder = 0
DesignSize = (
246
46)
object btn1: TButton
Left = 150
Top = 10
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'btn1'
TabOrder = 0
end
end
end
This appears to be a bug in Delphi. I recreated the same behavior using your above code in Delphi 10 Seattle.
The only thing you can really do is to not set these particular bevels in design-time. Instead, set that in run-time...
pnl1.BevelKind := bkFlat;
Chances are, without digging into the controls, is that the order in which the properties are streamed from the DFM is in just the right (or wrong) order to the point where, perhaps, the button gets positioned before the panel is the size it needs to be, for example. I can't imagine a fix you could do without completely re-building the VCL, which is way out of the question.
You should submit a QC report to Embarcadero, if nobody has reported this issue yet.