How do I restrict a minimum form's width in FireMonkey? It used to be so easy in VCL - it just had Max and Min constraints in forms properties.
This will only work for versions below XE3 because the Fmx::Platform::TPlatform
class was removed in XE3. Thanks to @Alain Thiffault for pointing it out in the comments.
Here's a more complicated (but more elegant) alternative solution, defining an entirely custom Form class from which you can inherit your own...
unit FMX.ConstrainedForm;
interface
uses
System.Classes, System.Types, System.UITypes, FMX.Forms, FMX.Platform, FMX.Types;
type
TFormConstraints = class(TPersistent)
private
FMaxHeight: Integer;
FMaxLeft: Integer;
FMaxWidth: Integer;
FMaxTop: Integer;
FMinHeight: Integer;
FMinLeft: Integer;
FMinWidth: Integer;
FMinTop: Integer;
public
constructor Create;
published
property MaxHeight: Integer read FMaxHeight write FMaxHeight default 0;
property MaxLeft: Integer read FMaxLeft write FMaxLeft default 0;
property MaxWidth: Integer read FMaxWidth write FMaxWidth default 0;
property MaxTop: Integer read FMaxTop write FMaxTop default 0;
property MinHeight: Integer read FMinHeight write FMinHeight default 0;
property MinLeft: Integer read FMinLeft write FMinLeft default 0;
property MinWidth: Integer read FMinWidth write FMinWidth default 0;
property MinTop: Integer read FMinTop write FMinTop default 0;
end;
TConstrainedForm = class(TCustomForm)
private
FConstraints: TFormConstraints;
protected
procedure StartWindowResize; override;
procedure StartWindowDrag; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property Constraints: TFormConstraints read FConstraints write FConstraints;
property BiDiMode;
property Caption;
property Cursor default crDefault;
property BorderStyle default TFmxFormBorderStyle.bsSizeable;
property BorderIcons default [TBorderIcon.biSystemMenu, TBorderIcon.biMinimize, TBorderIcon.biMaximize];
property ClientHeight;
property ClientWidth;
property Left;
property Top;
property Margins;
property Position default TFormPosition.poDefaultPosOnly;
property Width;
property Height;
property ShowActivated default True;
property StaysOpen default True;
property Transparency;
property TopMost default False;
property Visible;
property WindowState default TWindowState.wsNormal;
property OnCreate;
property OnDestroy;
property OnClose;
property OnCloseQuery;
property OnActivate;
property OnDeactivate;
property OnResize;
property Fill;
property StyleBook;
property ActiveControl;
property StyleLookup;
property OnPaint;
end;
procedure Register;
implementation
{ TFormConstraints }
constructor TFormConstraints.Create;
begin
inherited;
FMaxHeight := 0;
FMaxLeft := 0;
FMaxWidth := 0;
FMaxTop := 0;
FMinHeight := 0;
FMinLeft := 0;
FMinWidth := 0;
FMinTop := 0;
end;
{ TConstrainedForm }
constructor TConstrainedForm.Create(AOwner: TComponent);
begin
FConstraints := TFormConstraints.Create;
inherited;
end;
destructor TConstrainedForm.Destroy;
begin
FConstraints.Free;
inherited;
end;
procedure TConstrainedForm.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
if (FConstraints.FMinWidth > 0) and (AWidth < FConstraints.FMinWidth) then
AWidth := FConstraints.FMinWidth;
if (FConstraints.FMaxWidth > 0) and (AWidth > FConstraints.FMaxWidth) then
AWidth := FConstraints.FMaxWidth;
if (FConstraints.FMinHeight > 0) and (AHeight < FConstraints.FMinHeight) then
AHeight := FConstraints.FMinHeight;
if (FConstraints.FMaxHeight > 0) and (AHeight > FConstraints.FMaxHeight) then
AHeight := FConstraints.FMaxHeight;
if (FConstraints.FMinLeft > 0) and (ALeft < FConstraints.FMinLeft) then
ALeft := FConstraints.FMinLeft;
if (FConstraints.FMaxLeft > 0) and (ALeft > FConstraints.FMaxLeft) then
ALeft := FConstraints.FMaxLeft;
if (FConstraints.FMinTop > 0) and (ATop < FConstraints.FMinTop) then
ATop := FConstraints.FMinTop;
if (FConstraints.FMaxTop > 0) and (ATop > FConstraints.FMaxTop) then
ATop := FConstraints.FMaxTop;
Platform.SetWindowRect(Self, RectF(ALeft, ATop, ALeft + AWidth, ATop + AHeight));
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TConstrainedForm.StartWindowDrag;
begin
inherited;
end;
procedure TConstrainedForm.StartWindowResize;
begin
inherited;
end;
procedure Register;
begin
RegisterClass(TConstrainedForm);
end;
end.
Store this file as FMX.ConstrainedForm.pas, add it to your Form's "uses" section, and modify the declaration of your form so that instead of:
TForm1 = class(TForm)
it says:
TForm1 = class(TConstrainedForm)
Due to the lack of a custom designed (at this point anyway, this is a "quick solution"), you then need to hook your form's OnCreate event as follows:
procedure TForm1.FormCreate(Sender: TObject);
begin
Constraints.MinWidth := 400;
Constraints.MinHeight := 400;
end;
Now this form will not allow the user to set its width or height below 400!
Again, without making some substancial changes to the FireMonkey Platform itself, this is the best you're going to get for now!