I have a small problem with anchors.
I have a form with 2 panels, Panel1
is aligned to left and Panel2
is on the first, not aligned but anchored top and bottom. On the second panel there are two edits, they are anchored left, right and bottom only. This design causes a "minimizing" sliding effect whereby the edits disappear at the top when the form is resized. This is intended.
On the start of the application, the initial state of the second panel should be invisible, thus I use Panel2.Height := 0
.
But after resizing the form, or manually setting Panel2.Height := 104
, the edits are not dragged down to their anchored positions, but they remain invisible beyond the panel.
This is the sample code which could help to visualize it:
// unit 1
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TMoveEvent = procedure (Sender: TObject; X, Y: Integer) of object;
TLabeledEdit = class(ExtCtrls.TLabeledEdit)
private
FOnMove: TMoveEvent;
procedure WMMove(var Message: TWMMove); message WM_MOVE;
public
property OnMove: TMoveEvent read FOnMove write FOnMove;
end;
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
LabeledEdit1: TLabeledEdit;
LabeledEdit2: TLabeledEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure LE1Move(Sender: TObject; X, Y: Integer);
procedure LE2Move(Sender: TObject; X, Y: Integer);
public
procedure AfterConstruction; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
TypInfo;
const
MaxSet = 255; // Largest ordinal value in a Delphi set.
type
TSet = set of 0..MaxSet;
function SetToString(Info: PTypeInfo; const Value; const Separator, Prefix, Suffix: string): String; overload;
var
CompInfo: PTypeInfo;
CompData: PTypeData;
SetValue: TSet absolute Value;
Element: 0..MaxSet;
begin
CompInfo:=GetTypeData(Info)^.CompType^;
CompData:=GetTypeData(CompInfo);
Result:='';
for Element:=CompData.MinValue to CompData.MaxValue do begin
if Element in SetValue then
if Result = '' then
Result := Prefix + GetEnumName(CompInfo, Element)
else
Result := Result + Separator + GetEnumName(CompInfo, Element);
end;
if Result = '' then
Result := Prefix + Suffix
else
Result := Result + Suffix;
end;
function SetToString(Info: PTypeInfo; const Value; const Separator: string): String; overload;
begin
Result:=SetToString(Info, Value, Separator, '[', ']');
end;
function SetToString(Info: PTypeInfo; const Value): String; overload;
begin
Result:=SetToString(Info, Value, ', ');
end;
{ TLabeledEdit }
procedure TLabeledEdit.WMMove(var Message: TWMMove);
begin
inherited;
if Assigned(FOnMove) then
FOnMove(Self, Message.XPos, Message.YPos);
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
LabeledEdit1.OnMove:=LE1Move;
LabeledEdit2.OnMove:=LE2Move;
end;
procedure TForm1.AfterConstruction;
begin
inherited;
Panel2.Height:=0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Panel2.Height:=0;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Panel2.Height:=104;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage('LE1 Anchors = ' + SetToString(TypeInfo(TAnchors), LabeledEdit1.Anchors));
ShowMessage('LE2 Anchors = ' + SetToString(TypeInfo(TAnchors), LabeledEdit2.Anchors));
end;
procedure TForm1.LE1Move(Sender: TObject; X, Y: Integer);
begin
Label1.Caption:=Format('LE1 pos: %d : %d', [X, Y]);
end;
procedure TForm1.LE2Move(Sender: TObject; X, Y: Integer);
begin
Label2.Caption:=Format('LE2 pos: %d : %d', [X, Y]);
end;
end.
// dfm
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 304
ClientWidth = 643
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 200
Top = 56
Width = 31
Height = 13
Caption = 'Label1'
end
object Label2: TLabel
Left = 200
Top = 96
Width = 31
Height = 13
Caption = 'Label2'
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 185
Height = 304
Align = alLeft
TabOrder = 0
ExplicitLeft = 152
ExplicitTop = 96
ExplicitHeight = 41
DesignSize = (
185
304)
object Panel2: TPanel
Left = 1
Top = 81
Width = 183
Height = 104
Anchors = [akLeft, akTop, akRight, akBottom]
Constraints.MaxHeight = 104
TabOrder = 0
DesignSize = (
183
104)
object LabeledEdit1: TLabeledEdit
Left = 8
Top = 24
Width = 121
Height = 21
Anchors = [akLeft, akRight, akBottom]
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit1'
TabOrder = 0
end
object LabeledEdit2: TLabeledEdit
Left = 48
Top = 72
Width = 121
Height = 21
Anchors = [akLeft, akRight, akBottom]
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit2'
TabOrder = 1
end
end
end
object Button1: TButton
Left = 200
Top = 8
Width = 75
Height = 25
Caption = 'Hide'
TabOrder = 1
OnClick = Button1Click
end
object Button2: TButton
Left = 281
Top = 8
Width = 75
Height = 25
Caption = 'Show'
TabOrder = 2
OnClick = Button2Click
end
object Button3: TButton
Left = 200
Top = 140
Width = 75
Height = 25
Caption = 'Anchors'
TabOrder = 3
OnClick = Button3Click
end
end
If Panel2.Height
is not set to 0 after form create, the edits moves up and down when form is resized. If Panel2.Height
is set to 0 on form create, the edits stay invisible out of the Panel2
, and if Panel2
is shown, they stay invisible whereby the Top
positions are negative.
Can anybody help?
Two possible solutions:
Panel2
's height to zero in the form's OnShow
event instead of in AfterConstruction
, orPanel2
with Align=alBottom
.Exactly why the first solution does work I don't know, but it certainly has merit, because during OnCreate
(or AfterConstruction
as you use), the windowed control handles aren't allocated yet.