Search code examples
delphidelphi-xe6

Position of controls on panel with bevels


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.

enter image description here

enter image description here

enter image description here

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

Solution

  • 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.