Vielleicht kann man ja auch einen mix aus den beiden Ansätzen machen: Release der Maus, wenn einer der Minimalwerte (Breite oder Höhe) unterschritten ist und dann für diesen Wert - in einem Extra Thread - den Minimalwert setzen.
Im ResizeEvent kann man nach ReleaseCapture die angepassten Werte nicht setzen, da das Formular automatisch wieder auf die Ausgangsgröße zurückspringt, die es hatte, bevor man mit der Maus anfing, die Größe zu verändern. Selbst wenn man sich die Werte merkt und innerhalb des ResizeEvents nach ReleaseCapture setzt, geht es nicht. Daher kann man hier auf einen Task zugrückgreifen, der dann quasi in einem anderen Thread die Synchronisation mit dem Formular macht.
Kleiner Nachteil ist, dass der Anwender noch einmal mit der Maus ansetzen muss - wenn er eine Grenze unterschritten hat, z.B. die Breite - um dann den anderen Wert verändern zu können (z.B. dann die Höhe).
Jedenfalls flackert nichts mehr.
Delphi-Quellcode:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
System.Threading ;
// <------- wird hier wegen Task benötigt.
type
TForm1 =
class(TForm)
procedure FormResize(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
procedure DoConstraints (NewWidth, NewHeight: Integer);
end;
const
MIN_WIDTH = 300;
MIN_HEIGHT = 250;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.DoConstraints (NewWidth, NewHeight: Integer);
begin
setbounds (left, top, NewWidth, NewHeight);
end;
procedure TForm1.FormResize(Sender: TObject);
var
T: ITask;
w, h: Integer;
begin
if (width < MIN_WIDTH)
or (height < Min_Height)
then begin
if width < Min_Width
then w := Min_Width
else w := Width;
if height < Min_Height
then h := Min_Height
else h := Height;
ReleaseCapture;
T := TTask.Create(
procedure ()
begin
TThread.Synchronize(
nil,
procedure
begin
Self.DoConstraints (w, h);
end);
end);
T.Start;
end;
end;
end.
Muss allerdings anmerken, dass ich kein großer Threading-Experte bin. Vielleicht kann einer, der das ist, hier ein paar hilfreiche Anmerkungen machen, ob man das anders machen muss oder besser lösen kann. Da das hier ja nur zu grundsätzlichen Demonstration ist, habe ich auf Try ... Except Konstrukte verzichtet.
Wenn man hier eine abschließende Lösung gefunden hat, würde es sich natürlich noch anbieten, eine Extra Prozedur dafür anzulegen, die man dann im ResizeEvent nur noch aufrufen braucht und somit wiederverwendbar in anderen Projekten einsetzen kann.