Как ограничить минимальную ширину формы в FireMonkey? - PullRequest
9 голосов
/ 07 ноября 2011

Как ограничить минимальную ширину формы в FireMonkey?Раньше это было так просто в VCL - у него были ограничения Max и Min в свойствах форм.

Ответы [ 5 ]

14 голосов
/ 08 ноября 2011

Примечание для будущих читателей:

Это будет работать только для версий ниже XE3, поскольку класс Fmx::Platform::TPlatform был удален в XE3. Спасибо @Alain Thiffault за указание на это в комментариях.

Исходное сообщение:

Вот более сложное (но более элегантное) альтернативное решение, определяющее полностью собственный класс Form, от которого вы можете наследовать свой собственный ...

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.

Сохраните этот файл как FMX.ConstrainedForm.pas, добавьте его в раздел «Использование» вашей формы и измените объявление вашей формы так, чтобы вместо:

TForm1 = class(TForm)

это говорит:

TForm1 = class(TConstrainedForm)

Из-за отсутствия специально разработанного (на данный момент это «быстрое решение»), вам необходимо перехватить событие OnCreate вашей формы следующим образом:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Constraints.MinWidth := 400;
  Constraints.MinHeight := 400;
end;

Теперь эта форма не позволит пользователю устанавливать ее ширину или высоту ниже 400!

Опять же, без внесения каких-либо существенных изменений в саму платформу FireMonkey, это лучшее, что вы получите на данный момент!

6 голосов
/ 08 ноября 2011

Поместите это в событие формы OnResize, замените значения соответствующим образом.Конечно, это не лучшее решение в мире, но оно будет действовать до тех пор, пока свойства не будут повторно введены!

procedure TForm1.FormResize(Sender: TObject);
begin
  if Width < 400 then
    Width := 400;
  if Height < 400 then
    Height := 400;
end;

Приведенный выше код достаточно легко изменить для любой комбинации максимумов или минимумов, поэтомувесело!

4 голосов
/ 03 марта 2015

Дополнительно для ответа Лакравена о решении на основе FormResize используйте ClientWidth и ClientHeight вместо Width и Height, чтобы предотвратить растяжение формы.

procedure TForm1.FormResize(Sender: TObject);
begin
    if ClientWidth < 400 then
        ClientWidth := 400;
    if ClientHeight < 400 then
        ClientHeight := 400;
end;
4 голосов
/ 14 апреля 2013

Лакравен, смоделируйте событие mouseUp, чтобы избавиться от этого мерцания.

if (Width > maxWidth) then
begin
  Width := maxWidth;
  Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
end;
0 голосов
/ 02 мая 2019

Чтобы подытожить вышесказанное для полезного ответа, просто используйте код ниже:

Uses Winapi.Windows;

Procedure TForm1.FormResize(Sender: TObject);
Begin
 If ClientWidth < 400 Then
    Begin
      ClientWidth := 400;
      Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    End;

  If ClientHeight < 400 Then
    Begin
      ClientHeight := 400;
      Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    End;
End;
...